Browse Source

Fix Aggregator.buildAggregation on MULTI_BUCKETS aggregators.

Adrien Grand 11 years ago
parent
commit
d0143703a1

+ 15 - 5
src/main/java/org/elasticsearch/search/aggregations/bucket/BucketsAggregator.java

@@ -22,10 +22,10 @@ package org.elasticsearch.search.aggregations.bucket;
 import org.elasticsearch.common.util.BigArrays;
 import org.elasticsearch.common.util.LongArray;
 import org.elasticsearch.search.aggregations.Aggregator;
+import org.elasticsearch.search.aggregations.AggregatorFactories;
 import org.elasticsearch.search.aggregations.InternalAggregation;
 import org.elasticsearch.search.aggregations.InternalAggregations;
 import org.elasticsearch.search.aggregations.support.AggregationContext;
-import org.elasticsearch.search.aggregations.AggregatorFactories;
 
 import java.io.IOException;
 import java.util.Arrays;
@@ -75,17 +75,27 @@ public abstract class BucketsAggregator extends Aggregator {
      * Utility method to return the number of documents that fell in the given bucket (identified by the bucket ordinal)
      */
     protected final long bucketDocCount(long bucketOrd) {
-        assert bucketOrd < docCounts.size();
-        return docCounts.get(bucketOrd);
+        if (bucketOrd >= docCounts.size()) {
+            // This may happen eg. if no document in the highest buckets is accepted by a sub aggregator.
+            // For example, if there is a long terms agg on 3 terms 1,2,3 with a sub filter aggregator and if no document with 3 as a value
+            // matches the filter, then the filter will never collect bucket ord 3. However, the long terms agg will call bucketAggregations(3)
+            // on the filter aggregator anyway to build sub-aggregations.
+            return 0L;
+        } else {
+            return docCounts.get(bucketOrd);
+        }
     }
 
     /**
      * Utility method to build the aggregations of the given bucket (identified by the bucket ordinal)
      */
     protected final InternalAggregations bucketAggregations(long bucketOrd) {
-        InternalAggregation[] aggregations = new InternalAggregation[subAggregators.length];
+        final InternalAggregation[] aggregations = new InternalAggregation[subAggregators.length];
+        final long bucketDocCount = bucketDocCount(bucketOrd);
         for (int i = 0; i < subAggregators.length; i++) {
-            aggregations[i] = subAggregators[i].buildAggregation(bucketOrd);
+            aggregations[i] = bucketDocCount == 0L
+                    ? subAggregators[i].buildEmptyAggregation()
+                    : subAggregators[i].buildAggregation(bucketOrd);
         }
         return new InternalAggregations(Arrays.asList(aggregations));
     }

+ 1 - 5
src/main/java/org/elasticsearch/search/aggregations/bucket/nested/NestedAggregator.java

@@ -29,13 +29,9 @@ import org.elasticsearch.common.lucene.docset.DocIdSets;
 import org.elasticsearch.index.mapper.MapperService;
 import org.elasticsearch.index.mapper.object.ObjectMapper;
 import org.elasticsearch.index.search.nested.NonNestedDocsFilter;
-import org.elasticsearch.search.aggregations.AggregationExecutionException;
-import org.elasticsearch.search.aggregations.Aggregator;
-import org.elasticsearch.search.aggregations.InternalAggregation;
+import org.elasticsearch.search.aggregations.*;
 import org.elasticsearch.search.aggregations.bucket.SingleBucketAggregator;
 import org.elasticsearch.search.aggregations.support.AggregationContext;
-import org.elasticsearch.search.aggregations.AggregatorFactories;
-import org.elasticsearch.search.aggregations.AggregatorFactory;
 
 import java.io.IOException;