public TermsAggregator( String name, AggregatorFactories factories, AggregationContext context, Aggregator parent, BucketCountThresholds bucketCountThresholds, Terms.Order order, SubAggCollectionMode collectMode, List<Reducer> reducers, Map<String, Object> metaData) throws IOException { super(name, factories, context, parent, reducers, metaData); this.bucketCountThresholds = bucketCountThresholds; this.order = InternalOrder.validate(order, this); this.collectMode = collectMode; // Don't defer any child agg if we are dependent on it for pruning results if (order instanceof Aggregation) { AggregationPath path = ((Aggregation) order).path(); aggsUsedForSorting.add(path.resolveTopmostAggregator(this)); } else if (order instanceof CompoundOrder) { CompoundOrder compoundOrder = (CompoundOrder) order; for (Terms.Order orderElement : compoundOrder.orderElements()) { if (orderElement instanceof Aggregation) { AggregationPath path = ((Aggregation) orderElement).path(); aggsUsedForSorting.add(path.resolveTopmostAggregator(this)); } } } }
/** * Given a path and a set of buckets, this method will return the value inside the agg at that * path. This is used to extract values for use by pipeline aggregations (e.g. a derivative might * need the price for each bucket). If the bucket is empty, the configured GapPolicy is invoked to * resolve the missing bucket * * @param agg A series of agg buckets in the form of a histogram * @param bucket A specific bucket that a value needs to be extracted from. This bucket should be * present in the <code>histo</code> parameter * @param aggPath The path to a particular value that needs to be extracted. This path should * point to a metric inside the <code>bucket</code> * @param gapPolicy The gap policy to apply if empty buckets are found * @return The value extracted from <code>bucket</code> found at <code>aggPath</code> */ public static Double resolveBucketValue( MultiBucketsAggregation agg, InternalMultiBucketAggregation.Bucket bucket, String aggPath, GapPolicy gapPolicy) { List<String> aggPathsList = AggregationPath.parse(aggPath).getPathElementsAsStringList(); return resolveBucketValue(agg, bucket, aggPathsList, gapPolicy); }
@Test public void multiValueAggDerivative() throws Exception { SearchResponse response = client() .prepareSearch("idx") .addAggregation( histogram("histo") .field(SINGLE_VALUED_FIELD_NAME) .interval(interval) .subAggregation(stats("stats").field(SINGLE_VALUED_FIELD_NAME)) .subAggregation(derivative("deriv").setBucketsPaths("stats.sum"))) .execute() .actionGet(); assertSearchResponse(response); InternalHistogram<Bucket> deriv = response.getAggregations().get("histo"); assertThat(deriv, notNullValue()); assertThat(deriv.getName(), equalTo("histo")); assertThat(deriv.getBuckets().size(), equalTo(numValueBuckets)); Object[] propertiesKeys = (Object[]) deriv.getProperty("_key"); Object[] propertiesDocCounts = (Object[]) deriv.getProperty("_count"); Object[] propertiesSumCounts = (Object[]) deriv.getProperty("stats.sum"); List<Bucket> buckets = new ArrayList<Bucket>(deriv.getBuckets()); Long expectedSumPreviousBucket = Long.MIN_VALUE; // start value, gets // overwritten for (int i = 0; i < numValueBuckets; ++i) { Histogram.Bucket bucket = buckets.get(i); checkBucketKeyAndDocCount("Bucket " + i, bucket, i * interval, valueCounts[i]); Stats stats = bucket.getAggregations().get("stats"); assertThat(stats, notNullValue()); long expectedSum = valueCounts[i] * (i * interval); assertThat(stats.getSum(), equalTo((double) expectedSum)); SimpleValue sumDeriv = bucket.getAggregations().get("deriv"); if (i > 0) { assertThat(sumDeriv, notNullValue()); long sumDerivValue = expectedSum - expectedSumPreviousBucket; assertThat(sumDeriv.value(), equalTo((double) sumDerivValue)); assertThat( (double) bucket.getProperty( "histo", AggregationPath.parse("deriv.value").getPathElementsAsStringList()), equalTo((double) sumDerivValue)); } else { assertThat(sumDeriv, nullValue()); } expectedSumPreviousBucket = expectedSum; assertThat((long) propertiesKeys[i], equalTo((long) i * interval)); assertThat((long) propertiesDocCounts[i], equalTo(valueCounts[i])); assertThat((double) propertiesSumCounts[i], equalTo((double) expectedSum)); } }
private void resolveReducerOrder( Set<String> aggFactoryNames, Map<String, ReducerFactory> reducerFactoriesMap, List<ReducerFactory> orderedReducers, List<ReducerFactory> unmarkedFactories, Set<ReducerFactory> temporarilyMarked, ReducerFactory factory) { if (temporarilyMarked.contains(factory)) { throw new IllegalStateException( "Cyclical dependancy found with reducer [" + factory.getName() + "]"); } else if (unmarkedFactories.contains(factory)) { temporarilyMarked.add(factory); String[] bucketsPaths = factory.getBucketsPaths(); for (String bucketsPath : bucketsPaths) { List<String> bucketsPathElements = AggregationPath.parse(bucketsPath).getPathElementsAsStringList(); String firstAggName = bucketsPathElements.get(0); if (bucketsPath.equals("_count") || bucketsPath.equals("_key") || aggFactoryNames.contains(firstAggName)) { continue; } else { ReducerFactory matchingFactory = reducerFactoriesMap.get(firstAggName); if (matchingFactory != null) { resolveReducerOrder( aggFactoryNames, reducerFactoriesMap, orderedReducers, unmarkedFactories, temporarilyMarked, matchingFactory); } else { throw new IllegalStateException( "No aggregation found for path [" + bucketsPath + "]"); } } } unmarkedFactories.remove(factory); temporarilyMarked.remove(factory); orderedReducers.add(factory); } }
public void testSingleValuedFieldWithSubAggregation() throws Exception { SearchResponse response = client() .prepareSearch("idx") .addAggregation( dateHistogram("histo") .field("date") .dateHistogramInterval(DateHistogramInterval.MONTH) .minDocCount(0) .subAggregation(sum("sum").field("value")) .subAggregation(derivative("deriv", "sum"))) .execute() .actionGet(); assertSearchResponse(response); Histogram histo = response.getAggregations().get("histo"); assertThat(histo, notNullValue()); assertThat(histo.getName(), equalTo("histo")); List<? extends Bucket> buckets = histo.getBuckets(); assertThat(buckets.size(), equalTo(3)); Object[] propertiesKeys = (Object[]) histo.getProperty("_key"); Object[] propertiesDocCounts = (Object[]) histo.getProperty("_count"); Object[] propertiesCounts = (Object[]) histo.getProperty("sum.value"); DateTime key = new DateTime(2012, 1, 1, 0, 0, DateTimeZone.UTC); Histogram.Bucket bucket = buckets.get(0); assertThat(bucket, notNullValue()); assertThat((DateTime) bucket.getKey(), equalTo(key)); assertThat(bucket.getDocCount(), equalTo(1L)); assertThat(bucket.getAggregations().asList().isEmpty(), is(false)); Sum sum = bucket.getAggregations().get("sum"); assertThat(sum, notNullValue()); assertThat(sum.getValue(), equalTo(1.0)); SimpleValue deriv = bucket.getAggregations().get("deriv"); assertThat(deriv, nullValue()); assertThat((DateTime) propertiesKeys[0], equalTo(key)); assertThat((long) propertiesDocCounts[0], equalTo(1L)); assertThat((double) propertiesCounts[0], equalTo(1.0)); key = new DateTime(2012, 2, 1, 0, 0, DateTimeZone.UTC); bucket = buckets.get(1); assertThat(bucket, notNullValue()); assertThat((DateTime) bucket.getKey(), equalTo(key)); assertThat(bucket.getDocCount(), equalTo(2L)); assertThat(bucket.getAggregations().asList().isEmpty(), is(false)); sum = bucket.getAggregations().get("sum"); assertThat(sum, notNullValue()); assertThat(sum.getValue(), equalTo(5.0)); deriv = bucket.getAggregations().get("deriv"); assertThat(deriv, notNullValue()); assertThat(deriv.value(), equalTo(4.0)); assertThat( (double) bucket.getProperty( "histo", AggregationPath.parse("deriv.value").getPathElementsAsStringList()), equalTo(4.0)); assertThat((DateTime) propertiesKeys[1], equalTo(key)); assertThat((long) propertiesDocCounts[1], equalTo(2L)); assertThat((double) propertiesCounts[1], equalTo(5.0)); key = new DateTime(2012, 3, 1, 0, 0, DateTimeZone.UTC); bucket = buckets.get(2); assertThat(bucket, notNullValue()); assertThat((DateTime) bucket.getKey(), equalTo(key)); assertThat(bucket.getDocCount(), equalTo(3L)); assertThat(bucket.getAggregations().asList().isEmpty(), is(false)); sum = bucket.getAggregations().get("sum"); assertThat(sum, notNullValue()); assertThat(sum.getValue(), equalTo(15.0)); deriv = bucket.getAggregations().get("deriv"); assertThat(deriv, notNullValue()); assertThat(deriv.value(), equalTo(10.0)); assertThat( (double) bucket.getProperty( "histo", AggregationPath.parse("deriv.value").getPathElementsAsStringList()), equalTo(10.0)); assertThat((DateTime) propertiesKeys[2], equalTo(key)); assertThat((long) propertiesDocCounts[2], equalTo(3L)); assertThat((double) propertiesCounts[2], equalTo(15.0)); }