浏览代码

If no perBucketSample has been allocated for the parent bucket return a doc count of 0 (#59360)

Fabio Corneti 5 年之前
父节点
当前提交
9000bb4034

+ 3 - 0
server/src/main/java/org/elasticsearch/search/aggregations/bucket/sampler/BestDocsDeferringCollector.java

@@ -306,6 +306,9 @@ public class BestDocsDeferringCollector extends DeferringBucketCollector impleme
     }
     }
 
 
     public int getDocCount(long parentBucket) {
     public int getDocCount(long parentBucket) {
+        if (perBucketSamples.size() <= parentBucket) {
+            return 0;
+        }
         PerParentBucketSamples sampler = perBucketSamples.get((int) parentBucket);
         PerParentBucketSamples sampler = perBucketSamples.get((int) parentBucket);
         if (sampler == null) {
         if (sampler == null) {
             // There are conditions where no docs are collected and the aggs
             // There are conditions where no docs are collected and the aggs

+ 39 - 0
server/src/test/java/org/elasticsearch/search/aggregations/bucket/sampler/SamplerAggregatorTests.java

@@ -28,13 +28,20 @@ import org.apache.lucene.index.IndexWriter;
 import org.apache.lucene.index.IndexWriterConfig;
 import org.apache.lucene.index.IndexWriterConfig;
 import org.apache.lucene.index.Term;
 import org.apache.lucene.index.Term;
 import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.MatchAllDocsQuery;
 import org.apache.lucene.search.TermQuery;
 import org.apache.lucene.search.TermQuery;
 import org.apache.lucene.store.Directory;
 import org.apache.lucene.store.Directory;
 import org.elasticsearch.index.mapper.MappedFieldType;
 import org.elasticsearch.index.mapper.MappedFieldType;
 import org.elasticsearch.index.mapper.NumberFieldMapper;
 import org.elasticsearch.index.mapper.NumberFieldMapper;
 import org.elasticsearch.index.mapper.TextFieldMapper;
 import org.elasticsearch.index.mapper.TextFieldMapper;
 import org.elasticsearch.index.mapper.TextFieldMapper.TextFieldType;
 import org.elasticsearch.index.mapper.TextFieldMapper.TextFieldType;
+import org.elasticsearch.index.query.MatchAllQueryBuilder;
+import org.elasticsearch.index.query.MatchNoneQueryBuilder;
+import org.elasticsearch.index.query.QueryBuilder;
 import org.elasticsearch.search.aggregations.AggregatorTestCase;
 import org.elasticsearch.search.aggregations.AggregatorTestCase;
+import org.elasticsearch.search.aggregations.bucket.filter.FiltersAggregationBuilder;
+import org.elasticsearch.search.aggregations.bucket.filter.InternalFilters;
+import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
 import org.elasticsearch.search.aggregations.metrics.Min;
 import org.elasticsearch.search.aggregations.metrics.Min;
 import org.elasticsearch.search.aggregations.metrics.MinAggregationBuilder;
 import org.elasticsearch.search.aggregations.metrics.MinAggregationBuilder;
 import org.elasticsearch.search.aggregations.support.AggregationInspectionHelper;
 import org.elasticsearch.search.aggregations.support.AggregationInspectionHelper;
@@ -117,4 +124,36 @@ public class SamplerAggregatorTests extends AggregatorTestCase {
             }
             }
         }
         }
     }
     }
+
+    /**
+     * Tests that the sampler aggregation works correctly if the parent bucket does not contain any hit.
+     */
+    public void testEmptyParentBucket() throws Exception {
+        IndexWriterConfig indexWriterConfig = newIndexWriterConfig();
+        try (Directory dir = newDirectory();
+            IndexWriter writer = new IndexWriter(dir, indexWriterConfig)) {
+
+            writer.addDocument(new Document());
+
+            try (IndexReader reader = DirectoryReader.open(writer)) {
+                IndexSearcher searcher = new IndexSearcher(reader);
+
+                QueryBuilder[] filters = new QueryBuilder[]{
+                    new MatchAllQueryBuilder(),
+                    new MatchNoneQueryBuilder()
+                };
+                FiltersAggregationBuilder samplerParent = new FiltersAggregationBuilder("filters", filters);
+                TermsAggregationBuilder samplerChild = new TermsAggregationBuilder("child").field("field");
+                SamplerAggregationBuilder sampler = new SamplerAggregationBuilder("sampler")
+                    .subAggregation(samplerChild);
+                samplerParent.subAggregation(sampler);
+
+                InternalFilters response = searchAndReduce(searcher, new MatchAllDocsQuery(), samplerParent);
+                assertEquals(response.getBuckets().size(), 2);
+                assertEquals(response.getBuckets().get(0).getDocCount(), 1);
+                assertEquals(response.getBuckets().get(1).getDocCount(), 0);
+            }
+        }
+    }
+
 }
 }