Skip to content

Commit f9888ab

Browse files
committed
SQL: Preserve scoring in bool queries (elastic#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 elastic#29685
1 parent a97afba commit f9888ab

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
@@ -15,7 +15,6 @@
1515
import org.elasticsearch.client.Response;
1616
import org.elasticsearch.client.ResponseException;
1717
import org.elasticsearch.common.CheckedSupplier;
18-
import org.elasticsearch.common.Strings;
1918
import org.elasticsearch.common.collect.Tuple;
2019
import org.elasticsearch.common.io.Streams;
2120
import org.elasticsearch.common.xcontent.XContentHelper;
@@ -32,12 +31,11 @@
3231
import java.sql.JDBCType;
3332
import java.util.Arrays;
3433
import java.util.HashMap;
34+
import java.util.List;
3535
import java.util.Locale;
3636
import java.util.Map;
37-
import java.util.TreeMap;
3837

3938
import static java.util.Collections.emptyList;
40-
import static java.util.Collections.emptyMap;
4139
import static java.util.Collections.singletonList;
4240
import static java.util.Collections.singletonMap;
4341
import static java.util.Collections.unmodifiableMap;
@@ -428,19 +426,23 @@ public void testBasicTranslateQueryWithFilter() throws IOException {
428426
assertNotNull(query);
429427

430428
@SuppressWarnings("unchecked")
431-
Map<String, Object> constantScore = (Map<String, Object>) query.get("constant_score");
432-
assertNotNull(constantScore);
429+
Map<String, Object> bool = (Map<String, Object>) query.get("bool");
430+
assertNotNull(bool);
433431

434432
@SuppressWarnings("unchecked")
435-
Map<String, Object> filter = (Map<String, Object>) constantScore.get("filter");
433+
List<Object> filter = (List<Object>) bool.get("filter");
436434
assertNotNull(filter);
437435

438436
@SuppressWarnings("unchecked")
439-
Map<String, Object> match = (Map<String, Object>) filter.get("match");
440-
assertNotNull(match);
437+
Map<String, Object> map = (Map<String, Object>) filter.get(0);
438+
assertNotNull(map);
441439

442440
@SuppressWarnings("unchecked")
443-
Map<String, Object> matchQuery = (Map<String, Object>) match.get("test");
441+
Map<String, Object> matchQ = (Map<String, Object>) map.get("match");
442+
443+
@SuppressWarnings("unchecked")
444+
Map<String, Object> matchQuery = (Map<String, Object>) matchQ.get("test");
445+
444446
assertNotNull(matchQuery);
445447
assertEquals("foo", matchQuery.get("query"));
446448
}

0 commit comments

Comments
 (0)