Skip to content

Commit 9e95607

Browse files
committed
SQL: Preserve scoring in bool queries (#30730)
Make all bool constructs use match/should (that is a query context) as that is controlled and changed to a filter context by ES automatically based on the sort order (_doc, field vs _sort) and trackScores. Fix #29685
1 parent d8d01ee commit 9e95607

File tree

4 files changed

+33
-31
lines changed

4 files changed

+33
-31
lines changed

x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/execution/search/SourceGenerator.java

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55
*/
66
package org.elasticsearch.xpack.sql.execution.search;
77

8-
import org.elasticsearch.index.query.BoolQueryBuilder;
9-
import org.elasticsearch.index.query.ConstantScoreQueryBuilder;
108
import org.elasticsearch.index.query.QueryBuilder;
119
import org.elasticsearch.search.aggregations.AggregationBuilder;
1210
import org.elasticsearch.search.aggregations.bucket.composite.CompositeAggregationBuilder;
@@ -28,6 +26,7 @@
2826
import java.util.List;
2927

3028
import static java.util.Collections.singletonList;
29+
import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
3130
import static org.elasticsearch.search.sort.SortBuilders.fieldSort;
3231
import static org.elasticsearch.search.sort.SortBuilders.scoreSort;
3332
import static org.elasticsearch.search.sort.SortBuilders.scriptSort;
@@ -37,20 +36,23 @@ public abstract class SourceGenerator {
3736
private static final List<String> NO_STORED_FIELD = singletonList(StoredFieldsContext._NONE_);
3837

3938
public static SearchSourceBuilder sourceBuilder(QueryContainer container, QueryBuilder filter, Integer size) {
40-
final SearchSourceBuilder source = new SearchSourceBuilder();
39+
QueryBuilder finalQuery = null;
4140
// add the source
42-
if (container.query() == null) {
41+
if (container.query() != null) {
4342
if (filter != null) {
44-
source.query(new ConstantScoreQueryBuilder(filter));
43+
finalQuery = boolQuery().must(container.query().asBuilder()).filter(filter);
44+
} else {
45+
finalQuery = container.query().asBuilder();
4546
}
4647
} else {
4748
if (filter != null) {
48-
source.query(new BoolQueryBuilder().must(container.query().asBuilder()).filter(filter));
49-
} else {
50-
source.query(container.query().asBuilder());
49+
finalQuery = boolQuery().filter(filter);
5150
}
5251
}
5352

53+
final SearchSourceBuilder source = new SearchSourceBuilder();
54+
source.query(finalQuery);
55+
5456
SqlSourceBuilder sortBuilder = new SqlSourceBuilder();
5557
// Iterate through all the columns requested, collecting the fields that
5658
// need to be retrieved from the result documents

x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/querydsl/query/BoolQuery.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@
55
*/
66
package org.elasticsearch.xpack.sql.querydsl.query;
77

8-
import java.util.Objects;
9-
108
import org.elasticsearch.index.query.BoolQueryBuilder;
119
import org.elasticsearch.index.query.QueryBuilder;
1210
import org.elasticsearch.search.sort.NestedSortBuilder;
1311
import org.elasticsearch.xpack.sql.tree.Location;
1412

13+
import java.util.Objects;
14+
1515
import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
1616

1717
/**
@@ -63,9 +63,8 @@ public void enrichNestedSort(NestedSortBuilder sort) {
6363
public QueryBuilder asBuilder() {
6464
BoolQueryBuilder boolQuery = boolQuery();
6565
if (isAnd) {
66-
// TODO are we throwing out score by using filter?
67-
boolQuery.filter(left.asBuilder());
68-
boolQuery.filter(right.asBuilder());
66+
boolQuery.must(left.asBuilder());
67+
boolQuery.must(right.asBuilder());
6968
} else {
7069
boolQuery.should(left.asBuilder());
7170
boolQuery.should(right.asBuilder());

x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/execution/search/SourceGeneratorTests.java

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,6 @@
55
*/
66
package org.elasticsearch.xpack.sql.execution.search;
77

8-
import org.elasticsearch.index.query.BoolQueryBuilder;
9-
import org.elasticsearch.index.query.ConstantScoreQueryBuilder;
10-
import org.elasticsearch.index.query.MatchQueryBuilder;
118
import org.elasticsearch.index.query.Operator;
129
import org.elasticsearch.index.query.QueryBuilder;
1310
import org.elasticsearch.search.aggregations.AggregatorFactories.Builder;
@@ -28,6 +25,8 @@
2825
import org.elasticsearch.xpack.sql.type.KeywordEsField;
2926

3027
import static java.util.Collections.singletonList;
28+
import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
29+
import static org.elasticsearch.index.query.QueryBuilders.matchQuery;
3130
import static org.elasticsearch.search.sort.SortBuilders.fieldSort;
3231
import static org.elasticsearch.search.sort.SortBuilders.scoreSort;
3332

@@ -42,22 +41,22 @@ public void testNoQueryNoFilter() {
4241
public void testQueryNoFilter() {
4342
QueryContainer container = new QueryContainer().with(new MatchQuery(Location.EMPTY, "foo", "bar"));
4443
SearchSourceBuilder sourceBuilder = SourceGenerator.sourceBuilder(container, null, randomIntBetween(1, 10));
45-
assertEquals(new MatchQueryBuilder("foo", "bar").operator(Operator.OR), sourceBuilder.query());
44+
assertEquals(matchQuery("foo", "bar").operator(Operator.OR), sourceBuilder.query());
4645
}
4746

4847
public void testNoQueryFilter() {
4948
QueryContainer container = new QueryContainer();
50-
QueryBuilder filter = new MatchQueryBuilder("bar", "baz");
49+
QueryBuilder filter = matchQuery("bar", "baz");
5150
SearchSourceBuilder sourceBuilder = SourceGenerator.sourceBuilder(container, filter, randomIntBetween(1, 10));
52-
assertEquals(new ConstantScoreQueryBuilder(new MatchQueryBuilder("bar", "baz")), sourceBuilder.query());
51+
assertEquals(boolQuery().filter(matchQuery("bar", "baz")), sourceBuilder.query());
5352
}
5453

5554
public void testQueryFilter() {
5655
QueryContainer container = new QueryContainer().with(new MatchQuery(Location.EMPTY, "foo", "bar"));
57-
QueryBuilder filter = new MatchQueryBuilder("bar", "baz");
56+
QueryBuilder filter = matchQuery("bar", "baz");
5857
SearchSourceBuilder sourceBuilder = SourceGenerator.sourceBuilder(container, filter, randomIntBetween(1, 10));
59-
assertEquals(new BoolQueryBuilder().must(new MatchQueryBuilder("foo", "bar").operator(Operator.OR))
60-
.filter(new MatchQueryBuilder("bar", "baz")), sourceBuilder.query());
58+
assertEquals(boolQuery().must(matchQuery("foo", "bar").operator(Operator.OR)).filter(matchQuery("bar", "baz")),
59+
sourceBuilder.query());
6160
}
6261

6362
public void testLimit() {

x-pack/qa/sql/src/main/java/org/elasticsearch/xpack/qa/sql/rest/RestSqlTestCase.java

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
import org.elasticsearch.client.Response;
1717
import org.elasticsearch.client.ResponseException;
1818
import org.elasticsearch.common.CheckedSupplier;
19-
import org.elasticsearch.common.Strings;
2019
import org.elasticsearch.common.collect.Tuple;
2120
import org.elasticsearch.common.io.Streams;
2221
import org.elasticsearch.common.xcontent.XContentHelper;
@@ -33,12 +32,11 @@
3332
import java.sql.JDBCType;
3433
import java.util.Arrays;
3534
import java.util.HashMap;
35+
import java.util.List;
3636
import java.util.Locale;
3737
import java.util.Map;
38-
import java.util.TreeMap;
3938

4039
import static java.util.Collections.emptyList;
41-
import static java.util.Collections.emptyMap;
4240
import static java.util.Collections.singletonList;
4341
import static java.util.Collections.singletonMap;
4442
import static java.util.Collections.unmodifiableMap;
@@ -396,19 +394,23 @@ public void testBasicTranslateQueryWithFilter() throws IOException {
396394
assertNotNull(query);
397395

398396
@SuppressWarnings("unchecked")
399-
Map<String, Object> constantScore = (Map<String, Object>) query.get("constant_score");
400-
assertNotNull(constantScore);
397+
Map<String, Object> bool = (Map<String, Object>) query.get("bool");
398+
assertNotNull(bool);
401399

402400
@SuppressWarnings("unchecked")
403-
Map<String, Object> filter = (Map<String, Object>) constantScore.get("filter");
401+
List<Object> filter = (List<Object>) bool.get("filter");
404402
assertNotNull(filter);
405403

406404
@SuppressWarnings("unchecked")
407-
Map<String, Object> match = (Map<String, Object>) filter.get("match");
408-
assertNotNull(match);
405+
Map<String, Object> map = (Map<String, Object>) filter.get(0);
406+
assertNotNull(map);
409407

410408
@SuppressWarnings("unchecked")
411-
Map<String, Object> matchQuery = (Map<String, Object>) match.get("test");
409+
Map<String, Object> matchQ = (Map<String, Object>) map.get("match");
410+
411+
@SuppressWarnings("unchecked")
412+
Map<String, Object> matchQuery = (Map<String, Object>) matchQ.get("test");
413+
412414
assertNotNull(matchQuery);
413415
assertEquals("foo", matchQuery.get("query"));
414416
}

0 commit comments

Comments
 (0)