1515import org .apache .lucene .search .CollectionTerminatedException ;
1616import org .apache .lucene .search .IndexOrDocValuesQuery ;
1717import org .apache .lucene .search .IndexSortSortedNumericDocValuesRangeQuery ;
18+ import org .apache .lucene .search .LeafCollector ;
1819import org .apache .lucene .search .MatchAllDocsQuery ;
1920import org .apache .lucene .search .PointRangeQuery ;
2021import org .apache .lucene .search .Query ;
22+ import org .apache .lucene .search .Scorable ;
2123import org .apache .lucene .search .ScoreMode ;
22- import org .apache .lucene .search .TotalHitCountCollector ;
2324import org .apache .lucene .search .Weight ;
2425import org .apache .lucene .util .Bits ;
2526import org .elasticsearch .common .ParseField ;
3839import org .elasticsearch .search .aggregations .LeafBucketCollector ;
3940import org .elasticsearch .search .aggregations .LeafBucketCollectorBase ;
4041import org .elasticsearch .search .aggregations .bucket .BucketsAggregator ;
42+ import org .elasticsearch .search .aggregations .bucket .DocCountProvider ;
4143import org .elasticsearch .search .aggregations .support .AggregationContext ;
4244
4345import java .io .IOException ;
@@ -275,6 +277,11 @@ public static class FilterByFilter extends FiltersAggregator {
275277 */
276278 private BulkScorer [][] scorers ;
277279 private int segmentsWithDeletedDocs ;
280+ /**
281+ * Count of segments with documents have consult the {@code doc_count}
282+ * field.
283+ */
284+ private int segmentsWithDocCount ;
278285
279286 private FilterByFilter (
280287 String name ,
@@ -354,6 +361,10 @@ protected LeafBucketCollector getLeafCollector(LeafReaderContext ctx, LeafBucket
354361 weights = buildWeights (topLevelQuery (), filters );
355362 }
356363 Bits live = ctx .reader ().getLiveDocs ();
364+ Counter counter = new Counter (docCountProvider );
365+ if (false == docCountProvider .alwaysOne ()) {
366+ segmentsWithDocCount ++;
367+ }
357368 for (int filterOrd = 0 ; filterOrd < filters .length ; filterOrd ++) {
358369 BulkScorer scorer ;
359370 if (scorers == null ) {
@@ -367,9 +378,8 @@ protected LeafBucketCollector getLeafCollector(LeafReaderContext ctx, LeafBucket
367378 // the filter doesn't match any docs
368379 continue ;
369380 }
370- TotalHitCountCollector collector = new TotalHitCountCollector ();
371- scorer .score (collector , live );
372- incrementBucketDocCount (filterOrd , collector .getTotalHits ());
381+ scorer .score (counter , live );
382+ incrementBucketDocCount (filterOrd , counter .readAndReset (ctx ));
373383 }
374384 // Throwing this exception is how we communicate to the collection mechanism that we don't need the segment.
375385 throw new CollectionTerminatedException ();
@@ -379,13 +389,42 @@ protected LeafBucketCollector getLeafCollector(LeafReaderContext ctx, LeafBucket
379389 public void collectDebugInfo (BiConsumer <String , Object > add ) {
380390 super .collectDebugInfo (add );
381391 add .accept ("segments_with_deleted_docs" , segmentsWithDeletedDocs );
392+ add .accept ("segments_with_doc_count" , segmentsWithDocCount );
382393 if (estimatedCost != -1 ) {
383394 // -1 means we didn't estimate it.
384395 add .accept ("estimated_cost" , estimatedCost );
385396 add .accept ("max_cost" , maxCost );
386397 add .accept ("estimate_cost_time" , estimateCostTime );
387398 }
388399 }
400+
401+ /**
402+ * Counts collected documents, delegating to {@link DocCountProvider} for
403+ * how many documents each search hit is "worth".
404+ */
405+ private static class Counter implements LeafCollector {
406+ private final DocCountProvider docCount ;
407+ private long count ;
408+
409+ Counter (DocCountProvider docCount ) {
410+ this .docCount = docCount ;
411+ }
412+
413+ public long readAndReset (LeafReaderContext ctx ) throws IOException {
414+ long result = count ;
415+ count = 0 ;
416+ docCount .setLeafReaderContext (ctx );
417+ return result ;
418+ }
419+
420+ @ Override
421+ public void collect (int doc ) throws IOException {
422+ count += docCount .getDocCount (doc );
423+ }
424+
425+ @ Override
426+ public void setScorer (Scorable scorer ) throws IOException {}
427+ }
389428 }
390429
391430 /**
0 commit comments