use of io.druid.data.input.Row in project druid by druid-io.
the class DefaultLimitSpec method makeComparator.
private Ordering<Row> makeComparator(List<DimensionSpec> dimensions, List<AggregatorFactory> aggs, List<PostAggregator> postAggs) {
Ordering<Row> ordering = new Ordering<Row>() {
@Override
public int compare(Row left, Row right) {
return Longs.compare(left.getTimestampFromEpoch(), right.getTimestampFromEpoch());
}
};
Map<String, DimensionSpec> dimensionsMap = Maps.newHashMap();
for (DimensionSpec spec : dimensions) {
dimensionsMap.put(spec.getOutputName(), spec);
}
Map<String, AggregatorFactory> aggregatorsMap = Maps.newHashMap();
for (final AggregatorFactory agg : aggs) {
aggregatorsMap.put(agg.getName(), agg);
}
Map<String, PostAggregator> postAggregatorsMap = Maps.newHashMap();
for (PostAggregator postAgg : postAggs) {
postAggregatorsMap.put(postAgg.getName(), postAgg);
}
for (OrderByColumnSpec columnSpec : columns) {
String columnName = columnSpec.getDimension();
Ordering<Row> nextOrdering = null;
if (postAggregatorsMap.containsKey(columnName)) {
nextOrdering = metricOrdering(columnName, postAggregatorsMap.get(columnName).getComparator());
} else if (aggregatorsMap.containsKey(columnName)) {
nextOrdering = metricOrdering(columnName, aggregatorsMap.get(columnName).getComparator());
} else if (dimensionsMap.containsKey(columnName)) {
nextOrdering = dimensionOrdering(columnName, columnSpec.getDimensionComparator());
}
if (nextOrdering == null) {
throw new ISE("Unknown column in order clause[%s]", columnSpec);
}
switch(columnSpec.getDirection()) {
case DESCENDING:
nextOrdering = nextOrdering.reverse();
}
ordering = ordering.compound(nextOrdering);
}
return ordering;
}
use of io.druid.data.input.Row in project druid by druid-io.
the class GroupByStrategyV2 method mergeResults.
@Override
public Sequence<Row> mergeResults(final QueryRunner<Row> baseRunner, final GroupByQuery query, final Map<String, Object> responseContext) {
// Merge streams using ResultMergeQueryRunner, then apply postaggregators, then apply limit (which may
// involve materialization)
final ResultMergeQueryRunner<Row> mergingQueryRunner = new ResultMergeQueryRunner<Row>(baseRunner) {
@Override
protected Ordering<Row> makeOrdering(Query<Row> queryParam) {
return ((GroupByQuery) queryParam).getRowOrdering(true);
}
@Override
protected BinaryFn<Row, Row, Row> createMergeFn(Query<Row> queryParam) {
return new GroupByBinaryFnV2((GroupByQuery) queryParam);
}
};
// Fudge timestamp, maybe.
final DateTime fudgeTimestamp = getUniversalTimestamp(query);
return query.applyLimit(Sequences.map(mergingQueryRunner.run(new GroupByQuery(query.getDataSource(), query.getQuerySegmentSpec(), query.getVirtualColumns(), query.getDimFilter(), query.getGranularity(), query.getDimensions(), query.getAggregatorSpecs(), // Don't do post aggs until the end of this method.
ImmutableList.<PostAggregator>of(), // Don't do "having" clause until the end of this method.
null, null, query.getContext()).withOverriddenContext(ImmutableMap.<String, Object>of("finalize", false, GroupByQueryConfig.CTX_KEY_STRATEGY, GroupByStrategySelector.STRATEGY_V2, CTX_KEY_FUDGE_TIMESTAMP, fudgeTimestamp == null ? "" : String.valueOf(fudgeTimestamp.getMillis()), CTX_KEY_OUTERMOST, false)), responseContext), new Function<Row, Row>() {
@Override
public Row apply(final Row row) {
if (!query.getContextBoolean(CTX_KEY_OUTERMOST, true)) {
return row;
}
if (query.getPostAggregatorSpecs().isEmpty() && fudgeTimestamp == null) {
return row;
}
final Map<String, Object> newMap;
if (query.getPostAggregatorSpecs().isEmpty()) {
newMap = ((MapBasedRow) row).getEvent();
} else {
newMap = Maps.newLinkedHashMap(((MapBasedRow) row).getEvent());
for (PostAggregator postAggregator : query.getPostAggregatorSpecs()) {
newMap.put(postAggregator.getName(), postAggregator.compute(newMap));
}
}
return new MapBasedRow(fudgeTimestamp != null ? fudgeTimestamp : row.getTimestamp(), newMap);
}
}));
}
use of io.druid.data.input.Row in project druid by druid-io.
the class SpatialDimensionRowTransformer method apply.
@Override
public InputRow apply(final InputRow row) {
final Map<String, List<String>> spatialLookup = Maps.newHashMap();
// remove all spatial dimensions
final List<String> finalDims = Lists.newArrayList(Iterables.filter(row.getDimensions(), new Predicate<String>() {
@Override
public boolean apply(String input) {
return !spatialDimensionMap.containsKey(input) && !spatialPartialDimNames.contains(input);
}
}));
InputRow retVal = new InputRow() {
@Override
public List<String> getDimensions() {
return finalDims;
}
@Override
public long getTimestampFromEpoch() {
return row.getTimestampFromEpoch();
}
@Override
public DateTime getTimestamp() {
return row.getTimestamp();
}
@Override
public List<String> getDimension(String dimension) {
List<String> retVal = spatialLookup.get(dimension);
return (retVal == null) ? row.getDimension(dimension) : retVal;
}
@Override
public Object getRaw(String dimension) {
List<String> retVal = spatialLookup.get(dimension);
return (retVal == null) ? row.getRaw(dimension) : retVal;
}
@Override
public long getLongMetric(String metric) {
try {
return row.getLongMetric(metric);
} catch (ParseException e) {
throw Throwables.propagate(e);
}
}
@Override
public float getFloatMetric(String metric) {
try {
return row.getFloatMetric(metric);
} catch (ParseException e) {
throw Throwables.propagate(e);
}
}
@Override
public String toString() {
return row.toString();
}
@Override
public int compareTo(Row o) {
return getTimestamp().compareTo(o.getTimestamp());
}
};
for (Map.Entry<String, SpatialDimensionSchema> entry : spatialDimensionMap.entrySet()) {
final String spatialDimName = entry.getKey();
final SpatialDimensionSchema spatialDim = entry.getValue();
List<String> dimVals = row.getDimension(spatialDimName);
if (dimVals != null && !dimVals.isEmpty()) {
if (dimVals.size() != 1) {
throw new ISE("Spatial dimension value must be in an array!");
}
if (isJoinedSpatialDimValValid(dimVals.get(0))) {
spatialLookup.put(spatialDimName, dimVals);
finalDims.add(spatialDimName);
}
} else {
List<String> spatialDimVals = Lists.newArrayList();
for (String dim : spatialDim.getDims()) {
List<String> partialDimVals = row.getDimension(dim);
if (isSpatialDimValsValid(partialDimVals)) {
spatialDimVals.addAll(partialDimVals);
}
}
if (spatialDimVals.size() == spatialDim.getDims().size()) {
spatialLookup.put(spatialDimName, Arrays.asList(JOINER.join(spatialDimVals)));
finalDims.add(spatialDimName);
}
}
}
return retVal;
}
use of io.druid.data.input.Row in project druid by druid-io.
the class MultiValuedDimensionTest method testGroupByNoFilter.
@Test
public void testGroupByNoFilter() throws Exception {
GroupByQuery query = GroupByQuery.builder().setDataSource("xx").setQuerySegmentSpec(new LegacySegmentSpec("1970/3000")).setGranularity(Granularities.ALL).setDimensions(Lists.<DimensionSpec>newArrayList(new DefaultDimensionSpec("tags", "tags"))).setAggregatorSpecs(Arrays.asList(new AggregatorFactory[] { new CountAggregatorFactory("count") })).build();
Sequence<Row> result = helper.runQueryOnSegmentsObjs(ImmutableList.<Segment>of(new QueryableIndexSegment("sid1", queryableIndex), new IncrementalIndexSegment(incrementalIndex, "sid2")), query);
List<Row> expectedResults = Arrays.asList(GroupByQueryRunnerTestHelper.createExpectedRow("1970-01-01T00:00:00.000Z", "tags", null, "count", 2L), GroupByQueryRunnerTestHelper.createExpectedRow("1970-01-01T00:00:00.000Z", "tags", "t1", "count", 2L), GroupByQueryRunnerTestHelper.createExpectedRow("1970-01-01T00:00:00.000Z", "tags", "t2", "count", 2L), GroupByQueryRunnerTestHelper.createExpectedRow("1970-01-01T00:00:00.000Z", "tags", "t3", "count", 4L), GroupByQueryRunnerTestHelper.createExpectedRow("1970-01-01T00:00:00.000Z", "tags", "t4", "count", 2L), GroupByQueryRunnerTestHelper.createExpectedRow("1970-01-01T00:00:00.000Z", "tags", "t5", "count", 4L), GroupByQueryRunnerTestHelper.createExpectedRow("1970-01-01T00:00:00.000Z", "tags", "t6", "count", 2L), GroupByQueryRunnerTestHelper.createExpectedRow("1970-01-01T00:00:00.000Z", "tags", "t7", "count", 2L));
TestHelper.assertExpectedObjects(expectedResults, Sequences.toList(result, new ArrayList<Row>()), "");
}
use of io.druid.data.input.Row in project druid by druid-io.
the class MultiValuedDimensionTest method testGroupByWithDimFilter.
@Test
public void testGroupByWithDimFilter() throws Exception {
GroupByQuery query = GroupByQuery.builder().setDataSource("xx").setQuerySegmentSpec(new LegacySegmentSpec("1970/3000")).setGranularity(Granularities.ALL).setDimensions(Lists.<DimensionSpec>newArrayList(new DefaultDimensionSpec("tags", "tags"))).setAggregatorSpecs(Arrays.asList(new AggregatorFactory[] { new CountAggregatorFactory("count") })).setDimFilter(new SelectorDimFilter("tags", "t3", null)).build();
Sequence<Row> result = helper.runQueryOnSegmentsObjs(ImmutableList.<Segment>of(new QueryableIndexSegment("sid1", queryableIndex), new IncrementalIndexSegment(incrementalIndex, "sid2")), query);
List<Row> expectedResults = Arrays.asList(GroupByQueryRunnerTestHelper.createExpectedRow("1970-01-01T00:00:00.000Z", "tags", "t1", "count", 2L), GroupByQueryRunnerTestHelper.createExpectedRow("1970-01-01T00:00:00.000Z", "tags", "t2", "count", 2L), GroupByQueryRunnerTestHelper.createExpectedRow("1970-01-01T00:00:00.000Z", "tags", "t3", "count", 4L), GroupByQueryRunnerTestHelper.createExpectedRow("1970-01-01T00:00:00.000Z", "tags", "t4", "count", 2L), GroupByQueryRunnerTestHelper.createExpectedRow("1970-01-01T00:00:00.000Z", "tags", "t5", "count", 2L));
TestHelper.assertExpectedObjects(expectedResults, Sequences.toList(result, new ArrayList<Row>()), "");
}
Aggregations