move extended bounds rounding to date histo agg builder

This commit is contained in:
Colin Goodheart-Smithe 2016-10-05 09:15:00 +01:00
parent cbb3cc625e
commit 5a308f8a5e
3 changed files with 62 additions and 67 deletions

View File

@ -21,6 +21,8 @@ package org.elasticsearch.search.aggregations.bucket.histogram;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.rounding.DateTimeUnit;
import org.elasticsearch.common.rounding.Rounding;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.search.aggregations.AggregatorFactories.Builder;
@ -35,8 +37,12 @@ import org.elasticsearch.search.aggregations.support.ValuesSourceConfig;
import org.elasticsearch.search.aggregations.support.ValuesSourceType;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import static java.util.Collections.unmodifiableMap;
/**
* A builder for histograms on date fields.
*/
@ -44,6 +50,29 @@ public class DateHistogramAggregationBuilder
extends ValuesSourceAggregationBuilder<ValuesSource.Numeric, DateHistogramAggregationBuilder> {
public static final String NAME = InternalDateHistogram.TYPE.name();
public static final Map<String, DateTimeUnit> DATE_FIELD_UNITS;
static {
Map<String, DateTimeUnit> dateFieldUnits = new HashMap<>();
dateFieldUnits.put("year", DateTimeUnit.YEAR_OF_CENTURY);
dateFieldUnits.put("1y", DateTimeUnit.YEAR_OF_CENTURY);
dateFieldUnits.put("quarter", DateTimeUnit.QUARTER);
dateFieldUnits.put("1q", DateTimeUnit.QUARTER);
dateFieldUnits.put("month", DateTimeUnit.MONTH_OF_YEAR);
dateFieldUnits.put("1M", DateTimeUnit.MONTH_OF_YEAR);
dateFieldUnits.put("week", DateTimeUnit.WEEK_OF_WEEKYEAR);
dateFieldUnits.put("1w", DateTimeUnit.WEEK_OF_WEEKYEAR);
dateFieldUnits.put("day", DateTimeUnit.DAY_OF_MONTH);
dateFieldUnits.put("1d", DateTimeUnit.DAY_OF_MONTH);
dateFieldUnits.put("hour", DateTimeUnit.HOUR_OF_DAY);
dateFieldUnits.put("1h", DateTimeUnit.HOUR_OF_DAY);
dateFieldUnits.put("minute", DateTimeUnit.MINUTES_OF_HOUR);
dateFieldUnits.put("1m", DateTimeUnit.MINUTES_OF_HOUR);
dateFieldUnits.put("second", DateTimeUnit.SECOND_OF_MINUTE);
dateFieldUnits.put("1s", DateTimeUnit.SECOND_OF_MINUTE);
DATE_FIELD_UNITS = unmodifiableMap(dateFieldUnits);
}
private long interval;
private DateHistogramInterval dateHistogramInterval;
private long offset = 0;
@ -245,13 +274,36 @@ public class DateHistogramAggregationBuilder
@Override
protected ValuesSourceAggregatorFactory<Numeric, ?> innerBuild(AggregationContext context, ValuesSourceConfig<Numeric> config,
AggregatorFactory<?> parent, Builder subFactoriesBuilder) throws IOException {
ExtendedBounds extendedBounds = null;
Rounding rounding = createRounding();
ExtendedBounds roundedBounds = null;
if (this.extendedBounds != null) {
// parse any string bounds to longs
extendedBounds = this.extendedBounds.parseAndValidate(name, context.searchContext(), config.format());
// parse any string bounds to longs and round
roundedBounds = this.extendedBounds.parseAndValidate(name, context.searchContext(), config.format()).round(rounding);
}
return new DateHistogramAggregatorFactory(name, type, config, interval, dateHistogramInterval, offset, order, keyed, minDocCount,
extendedBounds, context, parent, subFactoriesBuilder, metaData);
rounding, roundedBounds, context, parent, subFactoriesBuilder, metaData);
}
private Rounding createRounding() {
Rounding.Builder tzRoundingBuilder;
if (dateHistogramInterval != null) {
DateTimeUnit dateTimeUnit = DATE_FIELD_UNITS.get(dateHistogramInterval.toString());
if (dateTimeUnit != null) {
tzRoundingBuilder = Rounding.builder(dateTimeUnit);
} else {
// the interval is a time value?
tzRoundingBuilder = Rounding.builder(
TimeValue.parseTimeValue(dateHistogramInterval.toString(), null, getClass().getSimpleName() + ".interval"));
}
} else {
// the interval is an integer time value in millis?
tzRoundingBuilder = Rounding.builder(TimeValue.timeValueMillis(interval));
}
if (timeZone() != null) {
tzRoundingBuilder.timeZone(timeZone());
}
Rounding rounding = tzRoundingBuilder.build();
return rounding;
}
@Override

View File

@ -19,9 +19,7 @@
package org.elasticsearch.search.aggregations.bucket.histogram;
import org.elasticsearch.common.rounding.DateTimeUnit;
import org.elasticsearch.common.rounding.Rounding;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.search.aggregations.Aggregator;
import org.elasticsearch.search.aggregations.AggregatorFactories;
import org.elasticsearch.search.aggregations.AggregatorFactory;
@ -30,12 +28,9 @@ import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
import org.elasticsearch.search.aggregations.support.ValuesSource.Numeric;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static java.util.Collections.unmodifiableMap;
import org.elasticsearch.search.aggregations.support.AggregationContext;
import org.elasticsearch.search.aggregations.support.ValuesSource;
import org.elasticsearch.search.aggregations.support.ValuesSourceAggregatorFactory;
@ -44,29 +39,6 @@ import org.elasticsearch.search.aggregations.support.ValuesSourceConfig;
public final class DateHistogramAggregatorFactory
extends ValuesSourceAggregatorFactory<ValuesSource.Numeric, DateHistogramAggregatorFactory> {
public static final Map<String, DateTimeUnit> DATE_FIELD_UNITS;
static {
Map<String, DateTimeUnit> dateFieldUnits = new HashMap<>();
dateFieldUnits.put("year", DateTimeUnit.YEAR_OF_CENTURY);
dateFieldUnits.put("1y", DateTimeUnit.YEAR_OF_CENTURY);
dateFieldUnits.put("quarter", DateTimeUnit.QUARTER);
dateFieldUnits.put("1q", DateTimeUnit.QUARTER);
dateFieldUnits.put("month", DateTimeUnit.MONTH_OF_YEAR);
dateFieldUnits.put("1M", DateTimeUnit.MONTH_OF_YEAR);
dateFieldUnits.put("week", DateTimeUnit.WEEK_OF_WEEKYEAR);
dateFieldUnits.put("1w", DateTimeUnit.WEEK_OF_WEEKYEAR);
dateFieldUnits.put("day", DateTimeUnit.DAY_OF_MONTH);
dateFieldUnits.put("1d", DateTimeUnit.DAY_OF_MONTH);
dateFieldUnits.put("hour", DateTimeUnit.HOUR_OF_DAY);
dateFieldUnits.put("1h", DateTimeUnit.HOUR_OF_DAY);
dateFieldUnits.put("minute", DateTimeUnit.MINUTES_OF_HOUR);
dateFieldUnits.put("1m", DateTimeUnit.MINUTES_OF_HOUR);
dateFieldUnits.put("second", DateTimeUnit.SECOND_OF_MINUTE);
dateFieldUnits.put("1s", DateTimeUnit.SECOND_OF_MINUTE);
DATE_FIELD_UNITS = unmodifiableMap(dateFieldUnits);
}
private final DateHistogramInterval dateHistogramInterval;
private final long interval;
private final long offset;
@ -74,10 +46,11 @@ public final class DateHistogramAggregatorFactory
private final boolean keyed;
private final long minDocCount;
private final ExtendedBounds extendedBounds;
private Rounding rounding;
public DateHistogramAggregatorFactory(String name, Type type, ValuesSourceConfig<Numeric> config, long interval,
DateHistogramInterval dateHistogramInterval, long offset, InternalOrder order, boolean keyed, long minDocCount,
ExtendedBounds extendedBounds, AggregationContext context, AggregatorFactory<?> parent,
Rounding rounding, ExtendedBounds extendedBounds, AggregationContext context, AggregatorFactory<?> parent,
AggregatorFactories.Builder subFactoriesBuilder, Map<String, Object> metaData) throws IOException {
super(name, type, config, context, parent, subFactoriesBuilder, metaData);
this.interval = interval;
@ -87,34 +60,13 @@ public final class DateHistogramAggregatorFactory
this.keyed = keyed;
this.minDocCount = minDocCount;
this.extendedBounds = extendedBounds;
this.rounding = rounding;
}
public long minDocCount() {
return minDocCount;
}
private Rounding createRounding() {
Rounding.Builder tzRoundingBuilder;
if (dateHistogramInterval != null) {
DateTimeUnit dateTimeUnit = DATE_FIELD_UNITS.get(dateHistogramInterval.toString());
if (dateTimeUnit != null) {
tzRoundingBuilder = Rounding.builder(dateTimeUnit);
} else {
// the interval is a time value?
tzRoundingBuilder = Rounding.builder(
TimeValue.parseTimeValue(dateHistogramInterval.toString(), null, getClass().getSimpleName() + ".interval"));
}
} else {
// the interval is an integer time value in millis?
tzRoundingBuilder = Rounding.builder(TimeValue.timeValueMillis(interval));
}
if (timeZone() != null) {
tzRoundingBuilder.timeZone(timeZone());
}
Rounding rounding = tzRoundingBuilder.build();
return rounding;
}
@Override
protected Aggregator doCreateInternal(ValuesSource.Numeric valuesSource, Aggregator parent, boolean collectsFromSingleBucket,
List<PipelineAggregator> pipelineAggregators, Map<String, Object> metaData) throws IOException {
@ -126,17 +78,7 @@ public final class DateHistogramAggregatorFactory
private Aggregator createAggregator(ValuesSource.Numeric valuesSource, Aggregator parent, List<PipelineAggregator> pipelineAggregators,
Map<String, Object> metaData) throws IOException {
Rounding rounding = createRounding();
// we need to round the bounds given by the user and we have to do it
// for every aggregator we create
// as the rounding is not necessarily an idempotent operation.
// todo we need to think of a better structure to the factory/agtor
// code so we won't need to do that
ExtendedBounds roundedBounds = null;
if (extendedBounds != null) {
roundedBounds = extendedBounds.round(rounding);
}
return new DateHistogramAggregator(name, factories, rounding, offset, order, keyed, minDocCount, roundedBounds, valuesSource,
return new DateHistogramAggregator(name, factories, rounding, offset, order, keyed, minDocCount, extendedBounds, valuesSource,
config.format(), context, parent, pipelineAggregators, metaData);
}

View File

@ -32,6 +32,7 @@ import org.elasticsearch.search.DocValueFormat;
import org.elasticsearch.search.aggregations.AggregatorFactory;
import org.elasticsearch.search.aggregations.PipelineAggregationBuilder;
import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramAggregatorFactory;
import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramAggregationBuilder;
import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramInterval;
import org.elasticsearch.search.aggregations.bucket.histogram.HistogramAggregatorFactory;
import org.elasticsearch.search.aggregations.pipeline.AbstractPipelineAggregationBuilder;
@ -141,7 +142,7 @@ public class DerivativePipelineAggregationBuilder extends AbstractPipelineAggreg
}
Long xAxisUnits = null;
if (units != null) {
DateTimeUnit dateTimeUnit = DateHistogramAggregatorFactory.DATE_FIELD_UNITS.get(units);
DateTimeUnit dateTimeUnit = DateHistogramAggregationBuilder.DATE_FIELD_UNITS.get(units);
if (dateTimeUnit != null) {
xAxisUnits = dateTimeUnit.field(DateTimeZone.UTC).getDurationField().getUnitMillis();
} else {