Skip to content

Commit ab520d9

Browse files
authored
Fix needsScore computation in GlobalOrdCardinalityAggregator (#113129)
Only use TOP_DOCS if we are going to use dynamic pruning.
1 parent a1860f0 commit ab520d9

File tree

3 files changed

+100
-1
lines changed

3 files changed

+100
-1
lines changed

docs/changelog/113129.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
pr: 113129
2+
summary: Fix `needsScore` computation in `GlobalOrdCardinalityAggregator`
3+
area: Aggregations
4+
type: bug
5+
issues:
6+
- 112975

server/src/internalClusterTest/java/org/elasticsearch/search/aggregations/bucket/NestedIT.java

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
package org.elasticsearch.search.aggregations.bucket;
1010

1111
import org.apache.lucene.search.join.ScoreMode;
12+
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
1213
import org.elasticsearch.action.index.IndexRequestBuilder;
1314
import org.elasticsearch.action.search.SearchRequestBuilder;
1415
import org.elasticsearch.index.query.InnerHitBuilder;
@@ -18,11 +19,15 @@
1819
import org.elasticsearch.search.aggregations.InternalAggregation;
1920
import org.elasticsearch.search.aggregations.bucket.filter.Filter;
2021
import org.elasticsearch.search.aggregations.bucket.histogram.Histogram;
22+
import org.elasticsearch.search.aggregations.bucket.nested.InternalNested;
2123
import org.elasticsearch.search.aggregations.bucket.nested.Nested;
24+
import org.elasticsearch.search.aggregations.bucket.nested.NestedAggregationBuilder;
2225
import org.elasticsearch.search.aggregations.bucket.terms.LongTerms;
2326
import org.elasticsearch.search.aggregations.bucket.terms.StringTerms;
2427
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
2528
import org.elasticsearch.search.aggregations.bucket.terms.Terms.Bucket;
29+
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
30+
import org.elasticsearch.search.aggregations.metrics.CardinalityAggregationBuilder;
2631
import org.elasticsearch.search.aggregations.metrics.Max;
2732
import org.elasticsearch.search.aggregations.metrics.Stats;
2833
import org.elasticsearch.search.aggregations.metrics.Sum;
@@ -890,4 +895,87 @@ public void testSyntheticSource() throws Exception {
890895
assertEquals("a", nested.get("number"));
891896
});
892897
}
898+
899+
public void testScoring() throws Exception {
900+
assertAcked(
901+
prepareCreate("scoring").setMapping(
902+
jsonBuilder().startObject()
903+
.startObject("properties")
904+
.startObject("tags")
905+
.field("type", "nested")
906+
.startObject("properties")
907+
.startObject("key")
908+
.field("type", "keyword")
909+
.endObject()
910+
.startObject("value")
911+
.field("type", "keyword")
912+
.endObject()
913+
.endObject()
914+
.endObject()
915+
.endObject()
916+
.endObject()
917+
)
918+
);
919+
ensureGreen("scoring");
920+
921+
prepareIndex("scoring").setId("1")
922+
.setSource(
923+
jsonBuilder().startObject()
924+
.startArray("tags")
925+
.startObject()
926+
.field("key", "state")
927+
.field("value", "texas")
928+
.endObject()
929+
.endArray()
930+
.endObject()
931+
)
932+
.get();
933+
refresh("scoring");
934+
prepareIndex("scoring").setId("2")
935+
.setSource(
936+
jsonBuilder().startObject()
937+
.startArray("tags")
938+
.startObject()
939+
.field("key", "state")
940+
.field("value", "utah")
941+
.endObject()
942+
.endArray()
943+
.endObject()
944+
)
945+
.get();
946+
refresh("scoring");
947+
prepareIndex("scoring").setId("3")
948+
.setSource(
949+
jsonBuilder().startObject()
950+
.startArray("tags")
951+
.startObject()
952+
.field("key", "state")
953+
.field("value", "texas")
954+
.endObject()
955+
.endArray()
956+
.endObject()
957+
)
958+
.get();
959+
refresh("scoring");
960+
961+
assertResponse(
962+
client().prepareSearch("scoring")
963+
.setSize(0)
964+
.addAggregation(
965+
new NestedAggregationBuilder("tags", "tags").subAggregation(
966+
new TermsAggregationBuilder("keys").field("tags.key")
967+
.executionHint("map")
968+
.subAggregation(new TermsAggregationBuilder("values").field("tags.value"))
969+
.subAggregation(new CardinalityAggregationBuilder("values_count").field("tags.value"))
970+
)
971+
),
972+
searchResponse -> {
973+
InternalNested nested = searchResponse.getAggregations().get("tags");
974+
assertThat(nested.getDocCount(), equalTo(3L));
975+
assertThat(nested.getAggregations().asList().size(), equalTo(1));
976+
}
977+
);
978+
979+
assertAcked(indicesAdmin().delete(new DeleteIndexRequest("scoring")).get());
980+
}
893981
}

server/src/main/java/org/elasticsearch/search/aggregations/metrics/GlobalOrdCardinalityAggregator.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,12 @@ public GlobalOrdCardinalityAggregator(
9393

9494
@Override
9595
public ScoreMode scoreMode() {
96-
if (field != null && valuesSource.needsScores() == false && maxOrd <= MAX_FIELD_CARDINALITY_FOR_DYNAMIC_PRUNING) {
96+
// this check needs to line up with the dynamic pruning as it is the
97+
// only case where TOP_DOCS make sense.branch
98+
if (this.parent == null
99+
&& field != null
100+
&& valuesSource.needsScores() == false
101+
&& maxOrd <= MAX_FIELD_CARDINALITY_FOR_DYNAMIC_PRUNING) {
97102
return ScoreMode.TOP_DOCS;
98103
} else if (valuesSource.needsScores()) {
99104
return ScoreMode.COMPLETE;

0 commit comments

Comments
 (0)