From 83121e3e3a1807bb39bbcd019c620682c15369fd Mon Sep 17 00:00:00 2001 From: Ignacio Vera Date: Tue, 2 Dec 2025 12:38:37 +0100 Subject: [PATCH 1/2] Speed up LeafCollector#setScorer in TopHitsAggregator --- .../metrics/TopHitsAggregator.java | 50 +++++++++++++++++-- 1 file changed, 45 insertions(+), 5 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/search/aggregations/metrics/TopHitsAggregator.java b/server/src/main/java/org/elasticsearch/search/aggregations/metrics/TopHitsAggregator.java index 8ae4555479317..7a80c8845cacb 100644 --- a/server/src/main/java/org/elasticsearch/search/aggregations/metrics/TopHitsAggregator.java +++ b/server/src/main/java/org/elasticsearch/search/aggregations/metrics/TopHitsAggregator.java @@ -50,6 +50,7 @@ import java.io.IOException; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -115,14 +116,20 @@ public LeafBucketCollector getLeafCollector(AggregationExecutionContext aggCtx, leafCollectors = new LongObjectPagedHashMap<>(1, bigArrays); return new LeafBucketCollectorBase(sub, null) { - Scorable scorer; + // use the same Scorable for the leaf collectors + ResettableScorable scorer = null; @Override public void setScorer(Scorable scorer) throws IOException { - this.scorer = scorer; - super.setScorer(scorer); - for (Cursor leafCollector : leafCollectors) { - leafCollector.value.setScorer(scorer); + if (this.scorer != null) { + this.scorer.reset(scorer); + super.setScorer(scorer); + } else { + this.scorer = new ResettableScorable(scorer); + super.setScorer(scorer); + for (Cursor leafCollector : leafCollectors) { + leafCollector.value.setScorer(scorer); + } } } @@ -295,4 +302,37 @@ public void collectDebugInfo(BiConsumer add) { protected void doClose() { Releasables.close(topDocsCollectors, leafCollectors); } + + private static class ResettableScorable extends Scorable { + + private Scorable scorable; + + private ResettableScorable(Scorable scorable) { + this.scorable = scorable; + } + + private void reset(Scorable scorable) { + this.scorable = scorable; + } + + @Override + public float score() throws IOException { + return scorable.score(); + } + + @Override + public float smoothingScore(int docId) throws IOException { + return scorable.smoothingScore(docId); + } + + @Override + public void setMinCompetitiveScore(float minScore) throws IOException { + scorable.setMinCompetitiveScore(minScore); + } + + @Override + public Collection getChildren() throws IOException { + return scorable.getChildren(); + } + } } From f00d40a0e413e724e75eb351b471bf2c86e72cab Mon Sep 17 00:00:00 2001 From: Ignacio Vera Date: Tue, 2 Dec 2025 12:55:00 +0100 Subject: [PATCH 2/2] Update docs/changelog/138883.yaml --- docs/changelog/138883.yaml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 docs/changelog/138883.yaml diff --git a/docs/changelog/138883.yaml b/docs/changelog/138883.yaml new file mode 100644 index 0000000000000..3d76f8e8406d1 --- /dev/null +++ b/docs/changelog/138883.yaml @@ -0,0 +1,5 @@ +pr: 138883 +summary: Speed up `LeafCollector#setScorer` in `TopHitsAggregator` +area: Search +type: bug +issues: []