diff --git a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/BucketsAggregator.java b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/BucketsAggregator.java index 665dd49e3381d..e86c7127ec2f4 100644 --- a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/BucketsAggregator.java +++ b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/BucketsAggregator.java @@ -160,7 +160,8 @@ protected void prepareSubAggs(LongArray ordsToCollect) throws IOException {} * the provided ordinals. *
* Most aggregations should probably use something like
- * {@link #buildSubAggsForAllBuckets(ObjectArray, ToLongFunction, BiConsumer)}
+ * {@link #buildSubAggsForAllBuckets(ObjectArray, LongArray, BiConsumer)}
+ * or {@link #buildSubAggsForAllBuckets(ObjectArray, ToLongFunction, BiConsumer)}
* or {@link #buildAggregationsForVariableBuckets(LongArray, LongKeyedBucketOrds, BucketBuilderForVariable, ResultBuilderForVariable)}
* or {@link #buildAggregationsForFixedBucketCount(LongArray, int, BucketBuilderForFixedCount, Function)}
* or {@link #buildAggregationsForSingleBucket(LongArray, SingleBucketResultBuilder)}
@@ -193,10 +194,9 @@ public int size() {
}
/**
- * Build the sub aggregation results for a list of buckets and set them on
- * the buckets. This is usually used by aggregations that are selective
- * in which bucket they build. They use some mechanism of selecting a list
- * of buckets to build use this method to "finish" building the results.
+ * Similarly to {@link #buildSubAggsForAllBuckets(ObjectArray, LongArray, BiConsumer)}
+ * but it needs to build the bucket ordinals. This method usually requires for buckets
+ * to contain the bucket ordinal.
* @param buckets the buckets to finish building
* @param bucketToOrd how to convert a bucket into an ordinal
* @param setAggs how to set the sub-aggregation results on a bucket
@@ -218,12 +218,29 @@ protected final void buildSubAggsForAllBuckets(
bucketOrdsToCollect.set(s++, bucketToOrd.applyAsLong(bucket));
}
}
- var results = buildSubAggsForBuckets(bucketOrdsToCollect);
- s = 0;
- for (long ord = 0; ord < buckets.size(); ord++) {
- for (B value : buckets.get(ord)) {
- setAggs.accept(value, results.apply(s++));
- }
+ buildSubAggsForAllBuckets(buckets, bucketOrdsToCollect, setAggs);
+ }
+ }
+
+ /**
+ * Build the sub aggregation results for a list of buckets and set them on
+ * the buckets. This is usually used by aggregations that are selective
+ * in which bucket they build. They use some mechanism of selecting a list
+ * of buckets to build use this method to "finish" building the results.
+ * @param buckets the buckets to finish building
+ * @param bucketOrdsToCollect bucket ordinals
+ * @param setAggs how to set the sub-aggregation results on a bucket
+ */
+ protected final void buildSubAggsForAllBuckets(
+ ObjectArray buckets,
+ LongArray bucketOrdsToCollect,
+ BiConsumer setAggs
+ ) throws IOException {
+ var results = buildSubAggsForBuckets(bucketOrdsToCollect);
+ int s = 0;
+ for (long ord = 0; ord < buckets.size(); ord++) {
+ for (B value : buckets.get(ord)) {
+ setAggs.accept(value, results.apply(s++));
}
}
}
diff --git a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/geogrid/BucketPriorityQueue.java b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/geogrid/BucketPriorityQueue.java
index cc677605c4528..85c79df42a714 100644
--- a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/geogrid/BucketPriorityQueue.java
+++ b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/geogrid/BucketPriorityQueue.java
@@ -11,17 +11,24 @@
import org.elasticsearch.common.util.BigArrays;
import org.elasticsearch.common.util.ObjectArrayPriorityQueue;
-class BucketPriorityQueue extends ObjectArrayPriorityQueue {
+import java.util.function.Function;
- BucketPriorityQueue(int size, BigArrays bigArrays) {
+class BucketPriorityQueue extends ObjectArrayPriorityQueue {
+
+ private final Function bucketSupplier;
+
+ BucketPriorityQueue(int size, BigArrays bigArrays, Function bucketSupplier) {
super(size, bigArrays);
+ this.bucketSupplier = bucketSupplier;
}
@Override
- protected boolean lessThan(InternalGeoGridBucket o1, InternalGeoGridBucket o2) {
- int cmp = Long.compare(o2.getDocCount(), o1.getDocCount());
+ protected boolean lessThan(A o1, A o2) {
+ final B b1 = bucketSupplier.apply(o1);
+ final B b2 = bucketSupplier.apply(o2);
+ int cmp = Long.compare(b2.getDocCount(), b1.getDocCount());
if (cmp == 0) {
- cmp = o2.compareTo(o1);
+ cmp = b2.compareTo(b1);
if (cmp == 0) {
cmp = System.identityHashCode(o2) - System.identityHashCode(o1);
}
diff --git a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/geogrid/GeoGridAggregator.java b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/geogrid/GeoGridAggregator.java
index 1d3614af08768..b84dff6e73e0b 100644
--- a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/geogrid/GeoGridAggregator.java
+++ b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/geogrid/GeoGridAggregator.java
@@ -12,6 +12,7 @@
import org.apache.lucene.index.NumericDocValues;
import org.apache.lucene.index.SortedNumericDocValues;
import org.apache.lucene.search.ScoreMode;
+import org.elasticsearch.common.util.IntArray;
import org.elasticsearch.common.util.LongArray;
import org.elasticsearch.common.util.ObjectArray;
import org.elasticsearch.core.Releasables;
@@ -23,6 +24,7 @@
import org.elasticsearch.search.aggregations.LeafBucketCollector;
import org.elasticsearch.search.aggregations.LeafBucketCollectorBase;
import org.elasticsearch.search.aggregations.bucket.BucketsAggregator;
+import org.elasticsearch.search.aggregations.bucket.terms.BucketAndOrd;
import org.elasticsearch.search.aggregations.bucket.terms.LongKeyedBucketOrds;
import org.elasticsearch.search.aggregations.support.AggregationContext;
import org.elasticsearch.search.aggregations.support.ValuesSource;
@@ -135,34 +137,52 @@ public void collect(int doc, long owningBucketOrd) throws IOException {
@Override
public InternalAggregation[] buildAggregations(LongArray owningBucketOrds) throws IOException {
+
try (ObjectArray