|
30 | 30 | import org.elasticsearch.search.aggregations.BucketOrder; |
31 | 31 | import org.elasticsearch.search.aggregations.InternalAggregation; |
32 | 32 | import org.elasticsearch.search.aggregations.InternalOrder; |
| 33 | +import org.elasticsearch.search.aggregations.InternalOrder.CompoundOrder; |
33 | 34 | import org.elasticsearch.search.aggregations.NonCollectingAggregator; |
34 | 35 | import org.elasticsearch.search.aggregations.bucket.BucketUtils; |
35 | 36 | import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregator.BucketCountThresholds; |
@@ -93,6 +94,17 @@ public InternalAggregation buildEmptyAggregation() { |
93 | 94 | }; |
94 | 95 | } |
95 | 96 |
|
| 97 | + private static boolean isAggregationSort(BucketOrder order) { |
| 98 | + if (order instanceof InternalOrder.Aggregation) { |
| 99 | + return true; |
| 100 | + } else if (order instanceof InternalOrder.CompoundOrder) { |
| 101 | + InternalOrder.CompoundOrder compoundOrder = (CompoundOrder) order; |
| 102 | + return compoundOrder.orderElements().stream().anyMatch(TermsAggregatorFactory::isAggregationSort); |
| 103 | + } else { |
| 104 | + return false; |
| 105 | + } |
| 106 | + } |
| 107 | + |
96 | 108 | @Override |
97 | 109 | protected Aggregator doCreateInternal(ValuesSource valuesSource, Aggregator parent, boolean collectsFromSingleBucket, |
98 | 110 | List<PipelineAggregator> pipelineAggregators, Map<String, Object> metaData) throws IOException { |
@@ -139,10 +151,17 @@ protected Aggregator doCreateInternal(ValuesSource valuesSource, Aggregator pare |
139 | 151 | // to be unbounded and most instances may only aggregate few |
140 | 152 | // documents, so use hashed based |
141 | 153 | // global ordinals to keep the bucket ords dense. |
| 154 | + |
142 | 155 | // Additionally, if using partitioned terms the regular global |
143 | 156 | // ordinals would be sparse so we opt for hash |
| 157 | + |
| 158 | + // Finally if we are sorting by sub aggregations, then these |
| 159 | + // aggregations cannot be deferred, so global_ordinals_hash is |
| 160 | + // a safer choice as we won't use memory for sub aggregations |
| 161 | + // for buckets that are not collected. |
144 | 162 | if (Aggregator.descendsFromBucketAggregator(parent) || |
145 | | - (includeExclude != null && includeExclude.isPartitionBased())) { |
| 163 | + (includeExclude != null && includeExclude.isPartitionBased()) || |
| 164 | + isAggregationSort(order)) { |
146 | 165 | execution = ExecutionMode.GLOBAL_ORDINALS_HASH; |
147 | 166 | } else { |
148 | 167 | if (factories == AggregatorFactories.EMPTY) { |
|
0 commit comments