1919
2020package org .elasticsearch .search .aggregations .bucket .terms ;
2121
22- import org .apache .logging .log4j .LogManager ;
2322import org .apache .lucene .search .IndexSearcher ;
2423import org .elasticsearch .common .ParseField ;
25- import org .elasticsearch .common .logging .DeprecationLogger ;
2624import org .elasticsearch .index .query .QueryShardContext ;
2725import org .elasticsearch .search .DocValueFormat ;
2826import org .elasticsearch .search .aggregations .AggregationExecutionException ;
5250import java .util .function .Function ;
5351
5452public class TermsAggregatorFactory extends ValuesSourceAggregatorFactory {
55- private static final DeprecationLogger deprecationLogger = new DeprecationLogger (LogManager .getLogger (TermsAggregatorFactory .class ));
56-
5753 static Boolean REMAP_GLOBAL_ORDS , COLLECT_SEGMENT_ORDS ;
5854
59- private final BucketOrder order ;
60- private final IncludeExclude includeExclude ;
61- private final String executionHint ;
62- private final SubAggCollectionMode collectMode ;
63- private final TermsAggregator .BucketCountThresholds bucketCountThresholds ;
64- private final boolean showTermDocCountError ;
65-
6655 static void registerAggregators (ValuesSourceRegistry .Builder builder ) {
6756 builder .register (TermsAggregationBuilder .NAME ,
6857 Arrays .asList (CoreValuesSourceType .BYTES , CoreValuesSourceType .IP ),
@@ -98,7 +87,7 @@ public Aggregator build(String name,
9887
9988 ExecutionMode execution = null ;
10089 if (executionHint != null ) {
101- execution = ExecutionMode .fromString (executionHint , deprecationLogger );
90+ execution = ExecutionMode .fromString (executionHint );
10291 }
10392 // In some cases, using ordinals is just not supported: override it
10493 if (valuesSource instanceof ValuesSource .Bytes .WithOrdinals == false ) {
@@ -109,11 +98,7 @@ public Aggregator build(String name,
10998 }
11099 final long maxOrd = execution == ExecutionMode .GLOBAL_ORDINALS ? getMaxOrd (valuesSource , context .searcher ()) : -1 ;
111100 if (subAggCollectMode == null ) {
112- subAggCollectMode = SubAggCollectionMode .DEPTH_FIRST ;
113- // TODO can we remove concept of AggregatorFactories.EMPTY?
114- if (factories != AggregatorFactories .EMPTY ) {
115- subAggCollectMode = subAggCollectionMode (bucketCountThresholds .getShardSize (), maxOrd );
116- }
101+ subAggCollectMode = pickSubAggColectMode (factories , bucketCountThresholds .getShardSize (), maxOrd );
117102 }
118103
119104 if ((includeExclude != null ) && (includeExclude .isRegexBased ()) && format != DocValueFormat .RAW ) {
@@ -165,12 +150,7 @@ public Aggregator build(String name,
165150 }
166151
167152 if (subAggCollectMode == null ) {
168- // TODO can we remove concept of AggregatorFactories.EMPTY?
169- if (factories != AggregatorFactories .EMPTY ) {
170- subAggCollectMode = subAggCollectionMode (bucketCountThresholds .getShardSize (), -1 );
171- } else {
172- subAggCollectMode = SubAggCollectionMode .DEPTH_FIRST ;
173- }
153+ subAggCollectMode = pickSubAggColectMode (factories , bucketCountThresholds .getShardSize (), -1 );
174154 }
175155
176156 ValuesSource .Numeric numericValuesSource = (ValuesSource .Numeric ) valuesSource ;
@@ -198,6 +178,13 @@ public boolean needsToCollectFromSingleBucket() {
198178 };
199179 }
200180
181+ private final BucketOrder order ;
182+ private final IncludeExclude includeExclude ;
183+ private final String executionHint ;
184+ private final SubAggCollectionMode collectMode ;
185+ private final TermsAggregator .BucketCountThresholds bucketCountThresholds ;
186+ private final boolean showTermDocCountError ;
187+
201188 TermsAggregatorFactory (String name ,
202189 ValuesSourceConfig config ,
203190 BucketOrder order ,
@@ -280,17 +267,29 @@ protected Aggregator doCreateInternal(ValuesSource valuesSource,
280267 showTermDocCountError , collectsFromSingleBucket , metadata );
281268 }
282269
283- // return the SubAggCollectionMode that this aggregation should use based on the expected size
284- // and the cardinality of the field
285- static SubAggCollectionMode subAggCollectionMode (int expectedSize , long maxOrd ) {
270+ /**
271+ * Pick a {@link SubAggCollectionMode} based on heuristics about what
272+ * we're collecting.
273+ */
274+ static SubAggCollectionMode pickSubAggColectMode (AggregatorFactories factories , int expectedSize , long maxOrd ) {
275+ if (factories .countAggregators () == 0 ) {
276+ // Without sub-aggregations we pretty much ignore this field value so just pick something
277+ return SubAggCollectionMode .DEPTH_FIRST ;
278+ }
286279 if (expectedSize == Integer .MAX_VALUE ) {
287- // return all buckets
280+ // We expect to return all buckets so delaying them won't save any time
288281 return SubAggCollectionMode .DEPTH_FIRST ;
289282 }
290283 if (maxOrd == -1 || maxOrd > expectedSize ) {
291- // use breadth_first if the cardinality is bigger than the expected size or unknown (-1)
284+ /*
285+ * We either don't know how many buckets we expect there to be
286+ * (maxOrd == -1) or we expect there to be more buckets than
287+ * we will collect from this shard. So delaying collection of
288+ * the sub-buckets *should* save time.
289+ */
292290 return SubAggCollectionMode .BREADTH_FIRST ;
293291 }
292+ // We expect to collect so many buckets that we may as well collect them all.
294293 return SubAggCollectionMode .DEPTH_FIRST ;
295294 }
296295
@@ -398,7 +397,7 @@ Aggregator create(String name,
398397 }
399398 };
400399
401- public static ExecutionMode fromString (String value , final DeprecationLogger deprecationLogger ) {
400+ public static ExecutionMode fromString (String value ) {
402401 switch (value ) {
403402 case "global_ordinals" :
404403 return GLOBAL_ORDINALS ;
0 commit comments