Skip to content

Commit 2cc0a56

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 cacc3f7 commit 2cc0a56

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
@@ -509,8 +509,8 @@ private SpanQuery newSpanQuery(Term[] terms, boolean isPrefix) {
509509
}
510510
SpanQuery[] spanQueries = new SpanQuery[terms.length];
511511
for (int i = 0; i < terms.length; i++) {
512-
spanQueries[i] = isPrefix ? new SpanTermQuery(terms[i]) :
513-
fieldType.spanPrefixQuery(terms[i].text(), spanRewriteMethod, context);
512+
spanQueries[i] = isPrefix ? fieldType.spanPrefixQuery(terms[i].text(), spanRewriteMethod, context) :
513+
new SpanTermQuery(terms[i]);
514514
}
515515
return new SpanOrQuery(spanQueries);
516516
}

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;
@@ -463,6 +467,29 @@ public void testAutoGenerateSynonymsPhraseQuery() throws Exception {
463467
}
464468
}
465469

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

0 commit comments

Comments
 (0)