Skip to content

Commit 2e9f036

Browse files
committed
Fix wrong logic in match_phrase query with multi-word synonyms (#43941)
Disjunction over two individual terms in a phrase query with multi-word synonyms wrongly applies a prefix query to each of these terms. This change fixes this bug by inversing the logic to use prefixes on `phrase_prefix` queries only. Closes #43308
1 parent 7c9aa15 commit 2e9f036

File tree

2 files changed

+29
-2
lines changed

2 files changed

+29
-2
lines changed

server/src/main/java/org/elasticsearch/index/search/MatchQuery.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -505,8 +505,8 @@ private SpanQuery newSpanQuery(Term[] terms, boolean isPrefix) {
505505
}
506506
SpanQuery[] spanQueries = new SpanQuery[terms.length];
507507
for (int i = 0; i < terms.length; i++) {
508-
spanQueries[i] = isPrefix ? new SpanTermQuery(terms[i]) :
509-
fieldType.spanPrefixQuery(terms[i].text(), spanRewriteMethod, context);
508+
spanQueries[i] = isPrefix ? fieldType.spanPrefixQuery(terms[i].text(), spanRewriteMethod, context) :
509+
new SpanTermQuery(terms[i]);
510510
}
511511
return new SpanOrQuery(spanQueries);
512512
}

server/src/test/java/org/elasticsearch/index/query/MatchQueryBuilderTests.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@
3333
import org.apache.lucene.search.PointRangeQuery;
3434
import org.apache.lucene.search.Query;
3535
import org.apache.lucene.search.TermQuery;
36+
import org.apache.lucene.search.spans.SpanNearQuery;
37+
import org.apache.lucene.search.spans.SpanOrQuery;
38+
import org.apache.lucene.search.spans.SpanQuery;
39+
import org.apache.lucene.search.spans.SpanTermQuery;
3640
import org.apache.lucene.util.BytesRef;
3741
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
3842
import org.elasticsearch.common.ParsingException;
@@ -466,6 +470,29 @@ public void testAutoGenerateSynonymsPhraseQuery() throws Exception {
466470
}
467471
}
468472

473+
public void testMultiWordSynonymsPhrase() throws Exception {
474+
final MatchQuery matchQuery = new MatchQuery(createShardContext());
475+
matchQuery.setAnalyzer(new MockSynonymAnalyzer());
476+
final Query actual = matchQuery.parse(Type.PHRASE, STRING_FIELD_NAME, "guinea pig dogs");
477+
Query expected = SpanNearQuery.newOrderedNearQuery(STRING_FIELD_NAME)
478+
.addClause(
479+
new SpanOrQuery(new SpanQuery[]{
480+
SpanNearQuery.newOrderedNearQuery(STRING_FIELD_NAME)
481+
.addClause(new SpanTermQuery(new Term(STRING_FIELD_NAME, "guinea")))
482+
.addClause(new SpanTermQuery(new Term(STRING_FIELD_NAME, "pig")))
483+
.setSlop(0)
484+
.build(),
485+
new SpanTermQuery(new Term(STRING_FIELD_NAME, "cavy"))
486+
})
487+
)
488+
.addClause(new SpanOrQuery(new SpanQuery[]{
489+
new SpanTermQuery(new Term(STRING_FIELD_NAME, "dogs")),
490+
new SpanTermQuery(new Term(STRING_FIELD_NAME, "dog"))
491+
}))
492+
.build();
493+
assertEquals(expected, actual);
494+
}
495+
469496
public void testMaxBooleanClause() {
470497
MatchQuery query = new MatchQuery(createShardContext());
471498
query.setAnalyzer(new MockGraphAnalyzer(createGiantGraph(40)));

0 commit comments

Comments
 (0)