Skip to content

Commit 0d1a4ba

Browse files
authored
Fix named queries in the query rescorer (#94562)
This change fixes the handling of named queries when they appear in the query rescorer. Closes #65563
1 parent aba6c68 commit 0d1a4ba

File tree

7 files changed

+46
-13
lines changed

7 files changed

+46
-13
lines changed

server/src/internalClusterTest/java/org/elasticsearch/search/fetch/subphase/MatchedQueriesIT.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,14 @@
1111
import org.elasticsearch.action.search.SearchResponse;
1212
import org.elasticsearch.common.bytes.BytesReference;
1313
import org.elasticsearch.common.xcontent.XContentHelper;
14+
import org.elasticsearch.index.query.MatchAllQueryBuilder;
15+
import org.elasticsearch.index.query.MatchPhraseQueryBuilder;
1416
import org.elasticsearch.index.query.MatchQueryBuilder;
1517
import org.elasticsearch.index.query.QueryBuilder;
1618
import org.elasticsearch.index.query.QueryBuilders;
1719
import org.elasticsearch.index.query.TermQueryBuilder;
1820
import org.elasticsearch.search.SearchHit;
21+
import org.elasticsearch.search.rescore.QueryRescorerBuilder;
1922
import org.elasticsearch.test.ESIntegTestCase;
2023
import org.elasticsearch.xcontent.XContentType;
2124

@@ -339,4 +342,26 @@ public void testMatchedWithWrapperQuery() throws Exception {
339342
assertThat(searchResponse.getHits().getAt(0).getMatchedQueries()[0], equalTo("abc"));
340343
}
341344
}
345+
346+
public void testMatchedWithRescoreQuery() throws Exception {
347+
createIndex("test");
348+
ensureGreen();
349+
350+
client().prepareIndex("test").setId("1").setSource("content", "hello world").get();
351+
client().prepareIndex("test").setId("2").setSource("content", "hello you").get();
352+
refresh();
353+
354+
SearchResponse searchResponse = client().prepareSearch()
355+
.setQuery(new MatchAllQueryBuilder().queryName("all"))
356+
.setRescorer(
357+
new QueryRescorerBuilder(new MatchPhraseQueryBuilder("content", "hello you").boost(10).queryName("rescore_phrase"))
358+
)
359+
.get();
360+
assertHitCount(searchResponse, 2L);
361+
assertThat(searchResponse.getHits().getAt(0).getMatchedQueries().length, equalTo(2));
362+
assertThat(searchResponse.getHits().getAt(0).getMatchedQueries(), equalTo(new String[] { "all", "rescore_phrase" }));
363+
364+
assertThat(searchResponse.getHits().getAt(1).getMatchedQueries().length, equalTo(1));
365+
assertThat(searchResponse.getHits().getAt(1).getMatchedQueries(), equalTo(new String[] { "all" }));
366+
}
342367
}

server/src/main/java/org/elasticsearch/search/dfs/DfsPhase.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import org.apache.lucene.search.ScoreMode;
1717
import org.apache.lucene.search.TermStatistics;
1818
import org.apache.lucene.search.TopScoreDocCollector;
19+
import org.elasticsearch.index.query.ParsedQuery;
1920
import org.elasticsearch.index.query.SearchExecutionContext;
2021
import org.elasticsearch.search.builder.SearchSourceBuilder;
2122
import org.elasticsearch.search.internal.SearchContext;
@@ -122,11 +123,11 @@ public CollectionStatistics collectionStatistics(String field) throws IOExceptio
122123
maybeStop.accept(DfsTimingType.CREATE_WEIGHT);
123124
}
124125
for (RescoreContext rescoreContext : context.rescore()) {
125-
for (Query query : rescoreContext.getQueries()) {
126+
for (ParsedQuery parsedQuery : rescoreContext.getParsedQueries()) {
126127
final Query rewritten;
127128
try {
128129
maybeStart.accept(DfsTimingType.REWRITE);
129-
rewritten = searcher.rewrite(query);
130+
rewritten = searcher.rewrite(parsedQuery.query());
130131
} finally {
131132
maybeStop.accept(DfsTimingType.REWRITE);
132133
}

server/src/main/java/org/elasticsearch/search/fetch/subphase/MatchedQueriesPhase.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,12 @@
1414
import org.apache.lucene.search.Weight;
1515
import org.apache.lucene.util.Bits;
1616
import org.elasticsearch.common.lucene.Lucene;
17+
import org.elasticsearch.index.query.ParsedQuery;
1718
import org.elasticsearch.search.fetch.FetchContext;
1819
import org.elasticsearch.search.fetch.FetchSubPhase;
1920
import org.elasticsearch.search.fetch.FetchSubPhaseProcessor;
2021
import org.elasticsearch.search.fetch.StoredFieldsSpec;
22+
import org.elasticsearch.search.rescore.RescoreContext;
2123

2224
import java.io.IOException;
2325
import java.util.ArrayList;
@@ -35,6 +37,11 @@ public FetchSubPhaseProcessor getProcessor(FetchContext context) throws IOExcept
3537
if (context.parsedPostFilter() != null) {
3638
namedQueries.putAll(context.parsedPostFilter().namedFilters());
3739
}
40+
for (RescoreContext rescoreContext : context.rescore()) {
41+
for (ParsedQuery parsedQuery : rescoreContext.getParsedQueries()) {
42+
namedQueries.putAll(parsedQuery.namedFilters());
43+
}
44+
}
3845
if (namedQueries.isEmpty()) {
3946
return null;
4047
}

server/src/main/java/org/elasticsearch/search/rescore/QueryRescorer.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@
1010

1111
import org.apache.lucene.search.Explanation;
1212
import org.apache.lucene.search.IndexSearcher;
13-
import org.apache.lucene.search.Query;
1413
import org.apache.lucene.search.ScoreDoc;
1514
import org.apache.lucene.search.TopDocs;
15+
import org.elasticsearch.index.query.ParsedQuery;
1616

1717
import java.io.IOException;
1818
import java.util.Arrays;
@@ -37,7 +37,7 @@ public TopDocs rescore(TopDocs topDocs, IndexSearcher searcher, RescoreContext r
3737

3838
final QueryRescoreContext rescore = (QueryRescoreContext) rescoreContext;
3939

40-
org.apache.lucene.search.Rescorer rescorer = new org.apache.lucene.search.QueryRescorer(rescore.query()) {
40+
org.apache.lucene.search.Rescorer rescorer = new org.apache.lucene.search.QueryRescorer(rescore.parsedQuery().query()) {
4141

4242
@Override
4343
protected float combine(float firstPassScore, boolean secondPassMatches, float secondPassScore) {
@@ -90,7 +90,7 @@ public Explanation explain(int topLevelDocId, IndexSearcher searcher, RescoreCon
9090
prim = Explanation.noMatch("First pass did not match", sourceExplanation);
9191
}
9292
if (rescoreContext.isRescored(topLevelDocId)) {
93-
Explanation rescoreExplain = searcher.explain(rescore.query(), topLevelDocId);
93+
Explanation rescoreExplain = searcher.explain(rescore.parsedQuery().query(), topLevelDocId);
9494
// NOTE: we don't use Lucene's Rescorer.explain because we want to insert our own description with which ScoreMode was used.
9595
// Maybe we should add QueryRescorer.explainCombine to Lucene?
9696
if (rescoreExplain != null && rescoreExplain.isMatch()) {
@@ -152,7 +152,7 @@ private static TopDocs combine(TopDocs in, TopDocs resorted, QueryRescoreContext
152152
}
153153

154154
public static class QueryRescoreContext extends RescoreContext {
155-
private Query query;
155+
private ParsedQuery query;
156156
private float queryWeight = 1.0f;
157157
private float rescoreQueryWeight = 1.0f;
158158
private QueryRescoreMode scoreMode;
@@ -162,16 +162,16 @@ public QueryRescoreContext(int windowSize) {
162162
this.scoreMode = QueryRescoreMode.Total;
163163
}
164164

165-
public void setQuery(Query query) {
165+
public void setQuery(ParsedQuery query) {
166166
this.query = query;
167167
}
168168

169169
@Override
170-
public List<Query> getQueries() {
170+
public List<ParsedQuery> getParsedQueries() {
171171
return Collections.singletonList(query);
172172
}
173173

174-
public Query query() {
174+
public ParsedQuery parsedQuery() {
175175
return query;
176176
}
177177

server/src/main/java/org/elasticsearch/search/rescore/QueryRescorerBuilder.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ public static QueryRescorerBuilder fromXContent(XContentParser parser) throws IO
168168
public QueryRescoreContext innerBuildContext(int windowSize, SearchExecutionContext context) throws IOException {
169169
QueryRescoreContext queryRescoreContext = new QueryRescoreContext(windowSize);
170170
// query is rewritten at this point already
171-
queryRescoreContext.setQuery(queryBuilder.toQuery(context));
171+
queryRescoreContext.setQuery(context.toQuery(queryBuilder));
172172
queryRescoreContext.setQueryWeight(this.queryWeight);
173173
queryRescoreContext.setRescoreQueryWeight(this.rescoreQueryWeight);
174174
queryRescoreContext.setScoreMode(this.scoreMode);

server/src/main/java/org/elasticsearch/search/rescore/RescoreContext.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
package org.elasticsearch.search.rescore;
1010

11-
import org.apache.lucene.search.Query;
11+
import org.elasticsearch.index.query.ParsedQuery;
1212

1313
import java.util.Collections;
1414
import java.util.List;
@@ -62,7 +62,7 @@ public Set<Integer> getRescoredDocs() {
6262
/**
6363
* Returns queries associated with the rescorer
6464
*/
65-
public List<Query> getQueries() {
65+
public List<ParsedQuery> getParsedQueries() {
6666
return Collections.emptyList();
6767
}
6868
}

server/src/test/java/org/elasticsearch/search/rescore/QueryRescorerBuilderTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ public MappedFieldType getFieldType(String name) {
167167
: rescoreBuilder.windowSize().intValue();
168168
assertEquals(expectedWindowSize, rescoreContext.getWindowSize());
169169
Query expectedQuery = Rewriteable.rewrite(rescoreBuilder.getRescoreQuery(), mockContext).toQuery(mockContext);
170-
assertEquals(expectedQuery, rescoreContext.query());
170+
assertEquals(expectedQuery, rescoreContext.parsedQuery().query());
171171
assertEquals(rescoreBuilder.getQueryWeight(), rescoreContext.queryWeight(), Float.MIN_VALUE);
172172
assertEquals(rescoreBuilder.getRescoreQueryWeight(), rescoreContext.rescoreQueryWeight(), Float.MIN_VALUE);
173173
assertEquals(rescoreBuilder.getScoreMode(), rescoreContext.scoreMode());

0 commit comments

Comments
 (0)