use of org.apache.druid.query.aggregation.PostAggregator in project druid by druid-io.
the class DefaultLimitSpec method build.
@Override
public Function<Sequence<ResultRow>, Sequence<ResultRow>> build(final GroupByQuery query) {
final List<DimensionSpec> dimensions = query.getDimensions();
// Can avoid re-sorting if the natural ordering is good enough.
boolean sortingNeeded = dimensions.size() < columns.size();
final Set<String> aggAndPostAggNames = new HashSet<>();
for (AggregatorFactory agg : query.getAggregatorSpecs()) {
aggAndPostAggNames.add(agg.getName());
}
for (PostAggregator postAgg : query.getPostAggregatorSpecs()) {
aggAndPostAggNames.add(postAgg.getName());
}
if (!sortingNeeded) {
for (int i = 0; i < columns.size(); i++) {
final OrderByColumnSpec columnSpec = columns.get(i);
if (aggAndPostAggNames.contains(columnSpec.getDimension())) {
sortingNeeded = true;
break;
}
final ColumnType columnType = getOrderByType(columnSpec, dimensions);
final StringComparator naturalComparator;
if (columnType.is(ValueType.STRING)) {
naturalComparator = StringComparators.LEXICOGRAPHIC;
} else if (columnType.isNumeric()) {
naturalComparator = StringComparators.NUMERIC;
} else if (columnType.isArray()) {
if (columnType.getElementType().isNumeric()) {
naturalComparator = StringComparators.NUMERIC;
} else {
naturalComparator = StringComparators.LEXICOGRAPHIC;
}
} else {
sortingNeeded = true;
break;
}
if (columnSpec.getDirection() != OrderByColumnSpec.Direction.ASCENDING || !columnSpec.getDimensionComparator().equals(naturalComparator) || !columnSpec.getDimension().equals(dimensions.get(i).getOutputName())) {
sortingNeeded = true;
break;
}
}
}
if (!sortingNeeded) {
// If granularity is ALL, sortByDimsFirst doesn't change the sorting order.
sortingNeeded = !query.getGranularity().equals(Granularities.ALL) && query.getContextSortByDimsFirst();
}
if (!sortingNeeded) {
String timestampField = query.getContextValue(GroupByQuery.CTX_TIMESTAMP_RESULT_FIELD);
if (timestampField != null && !timestampField.isEmpty()) {
int timestampResultFieldIndex = query.getContextValue(GroupByQuery.CTX_TIMESTAMP_RESULT_FIELD_INDEX);
sortingNeeded = query.getContextSortByDimsFirst() ? timestampResultFieldIndex != query.getDimensions().size() - 1 : timestampResultFieldIndex != 0;
}
}
final Function<Sequence<ResultRow>, Sequence<ResultRow>> sortAndLimitFn;
if (sortingNeeded) {
// Materialize the Comparator first for fast-fail error checking.
final Ordering<ResultRow> ordering = makeComparator(query.getResultRowSignature(), query.getResultRowHasTimestamp(), query.getDimensions(), query.getAggregatorSpecs(), query.getPostAggregatorSpecs(), query.getContextSortByDimsFirst());
// underlying data isn't changing. (Useful for query reproducibility and offset-based pagination.)
if (isLimited()) {
sortAndLimitFn = results -> new TopNSequence<>(results, ordering, limit + offset);
} else {
sortAndLimitFn = results -> Sequences.sort(results, ordering).limit(limit + offset);
}
} else {
if (isLimited()) {
sortAndLimitFn = results -> results.limit(limit + offset);
} else {
sortAndLimitFn = Functions.identity();
}
}
// Finally, apply offset after sorting and limiting.
if (isOffset()) {
return results -> sortAndLimitFn.apply(results).skip(offset);
} else {
return sortAndLimitFn;
}
}
use of org.apache.druid.query.aggregation.PostAggregator in project druid by druid-io.
the class MomentSketchQuantilePostAggregatorTest method testComparator.
@Test
public void testComparator() {
expectedException.expect(IAE.class);
expectedException.expectMessage("Comparing arrays of quantiles is not supported");
PostAggregator postAgg = new MomentSketchQuantilePostAggregator("post", new ConstantPostAggregator("", 100), new double[] { 0.25, 0.75 });
postAgg.getComparator();
}
use of org.apache.druid.query.aggregation.PostAggregator in project druid by druid-io.
the class MomentSketchQuantilePostAggregatorTest method testToString.
@Test
public void testToString() {
PostAggregator postAgg = new MomentSketchQuantilePostAggregator("post", new ConstantPostAggregator("", 100), new double[] { 0.25, 0.75 });
Assert.assertEquals("MomentSketchQuantilePostAggregator{name='post', field=ConstantPostAggregator{name='', constantValue=100}, fractions=[0.25, 0.75]}", postAgg.toString());
}
use of org.apache.druid.query.aggregation.PostAggregator in project druid by druid-io.
the class MovingAverageIterable method generateEmptyEventsFromAggregators.
// Build a list of empty events from Aggregators/PostAggregators to be used by Iterator to build fake rows.
// These fake rows will be used by computeMovingAverage() in skip=true mode.
// See emptyEventsCopy in internalNext() and computeMovingAverage() documentation.
private Map<String, Object> generateEmptyEventsFromAggregators(Map<String, AggregatorFactory> aggMap, Map<String, PostAggregator> postAggMap) {
Map<String, Object> emptyEvents = new LinkedHashMap<>();
aggMap.values().forEach(agg -> {
Aggregator aggFactorized = agg.factorize(getEmptyColumnSelectorFactory());
emptyEvents.put(agg.getName(), aggFactorized.get());
});
postAggMap.values().forEach(postAgg -> emptyEvents.put(postAgg.getName(), postAgg.compute(emptyEvents)));
return emptyEvents;
}
use of org.apache.druid.query.aggregation.PostAggregator in project druid by druid-io.
the class TDigestSketchToQuantilesPostAggregatorTest method testToString.
@Test
public void testToString() {
PostAggregator postAgg = new TDigestSketchToQuantilesPostAggregator("post", new ConstantPostAggregator("", 100), new double[] { 0.25, 0.75 });
Assert.assertEquals("TDigestSketchToQuantilesPostAggregator{name='post', field=ConstantPostAggregator{name='', constantValue=100}, fractions=[0.25, 0.75]}", postAgg.toString());
}
Aggregations