Search in sources :

Example 1 with TopNMetricSpec

use of io.druid.query.topn.TopNMetricSpec in project druid by druid-io.

the class DruidQueryBuilder method toTopNQuery.

/**
   * Return this query as a TopN query, or null if this query is not compatible with TopN.
   *
   * @param dataSource         data source to query
   * @param sourceRowSignature row signature of the dataSource
   * @param context            query context
   * @param maxTopNLimit       maxTopNLimit from a PlannerConfig
   * @param useApproximateTopN from a PlannerConfig
   *
   * @return query or null
   */
public TopNQuery toTopNQuery(final DataSource dataSource, final RowSignature sourceRowSignature, final Map<String, Object> context, final int maxTopNLimit, final boolean useApproximateTopN) {
    // Must have GROUP BY one column, ORDER BY zero or one column, limit less than maxTopNLimit, and no HAVING.
    final boolean topNOk = grouping != null && grouping.getDimensions().size() == 1 && limitSpec != null && (limitSpec.getColumns().size() <= 1 && limitSpec.getLimit() <= maxTopNLimit) && having == null;
    if (!topNOk) {
        return null;
    }
    final DimensionSpec dimensionSpec = Iterables.getOnlyElement(grouping.getDimensions());
    final OrderByColumnSpec limitColumn;
    if (limitSpec.getColumns().isEmpty()) {
        limitColumn = new OrderByColumnSpec(dimensionSpec.getOutputName(), OrderByColumnSpec.Direction.ASCENDING, StringComparators.LEXICOGRAPHIC);
    } else {
        limitColumn = Iterables.getOnlyElement(limitSpec.getColumns());
    }
    final TopNMetricSpec topNMetricSpec;
    if (limitColumn.getDimension().equals(dimensionSpec.getOutputName())) {
        // DimensionTopNMetricSpec is exact; always return it even if allowApproximate is false.
        final DimensionTopNMetricSpec baseMetricSpec = new DimensionTopNMetricSpec(null, limitColumn.getDimensionComparator());
        topNMetricSpec = limitColumn.getDirection() == OrderByColumnSpec.Direction.ASCENDING ? baseMetricSpec : new InvertedTopNMetricSpec(baseMetricSpec);
    } else if (useApproximateTopN) {
        // ORDER BY metric
        final NumericTopNMetricSpec baseMetricSpec = new NumericTopNMetricSpec(limitColumn.getDimension());
        topNMetricSpec = limitColumn.getDirection() == OrderByColumnSpec.Direction.ASCENDING ? new InvertedTopNMetricSpec(baseMetricSpec) : baseMetricSpec;
    } else {
        return null;
    }
    final Filtration filtration = Filtration.create(filter).optimize(sourceRowSignature);
    return new TopNQuery(dataSource, VirtualColumns.EMPTY, Iterables.getOnlyElement(grouping.getDimensions()), topNMetricSpec, limitSpec.getLimit(), filtration.getQuerySegmentSpec(), filtration.getDimFilter(), Granularities.ALL, grouping.getAggregatorFactories(), grouping.getPostAggregators(), context);
}
Also used : OrderByColumnSpec(io.druid.query.groupby.orderby.OrderByColumnSpec) DimensionSpec(io.druid.query.dimension.DimensionSpec) DimensionTopNMetricSpec(io.druid.query.topn.DimensionTopNMetricSpec) InvertedTopNMetricSpec(io.druid.query.topn.InvertedTopNMetricSpec) Filtration(io.druid.sql.calcite.filtration.Filtration) NumericTopNMetricSpec(io.druid.query.topn.NumericTopNMetricSpec) TopNQuery(io.druid.query.topn.TopNQuery) TopNMetricSpec(io.druid.query.topn.TopNMetricSpec) NumericTopNMetricSpec(io.druid.query.topn.NumericTopNMetricSpec) DimensionTopNMetricSpec(io.druid.query.topn.DimensionTopNMetricSpec) InvertedTopNMetricSpec(io.druid.query.topn.InvertedTopNMetricSpec)

Aggregations

DimensionSpec (io.druid.query.dimension.DimensionSpec)1 OrderByColumnSpec (io.druid.query.groupby.orderby.OrderByColumnSpec)1 DimensionTopNMetricSpec (io.druid.query.topn.DimensionTopNMetricSpec)1 InvertedTopNMetricSpec (io.druid.query.topn.InvertedTopNMetricSpec)1 NumericTopNMetricSpec (io.druid.query.topn.NumericTopNMetricSpec)1 TopNMetricSpec (io.druid.query.topn.TopNMetricSpec)1 TopNQuery (io.druid.query.topn.TopNQuery)1 Filtration (io.druid.sql.calcite.filtration.Filtration)1