Skip to content

Commit afad5eb

Browse files
authored
Fix FuzzyQuery in keyword field when both of index and doc_value are true (#14378)
Signed-off-by: kkewwei <kkewwei@163.com>
1 parent 212efd7 commit afad5eb

File tree

5 files changed

+38
-4
lines changed

5 files changed

+38
-4
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
4444
- Fix aggs result of NestedAggregator with sub NestedAggregator ([#13324](https://github.com/opensearch-project/OpenSearch/pull/13324))
4545
- Fix fs info reporting negative available size ([#11573](https://github.com/opensearch-project/OpenSearch/pull/11573))
4646
- Add ListPitInfo::getKeepAlive() getter ([#14495](https://github.com/opensearch-project/OpenSearch/pull/14495))
47+
- Fix FuzzyQuery in keyword field will use IndexOrDocValuesQuery when both of index and doc_value are true ([#14378](https://github.com/opensearch-project/OpenSearch/pull/14378))
4748

4849
### Security
4950

server/src/main/java/org/opensearch/index/mapper/KeywordFieldMapper.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -549,7 +549,7 @@ public Query fuzzyQuery(
549549
);
550550
}
551551
if (isSearchable() && hasDocValues()) {
552-
Query indexQuery = super.fuzzyQuery(value, fuzziness, prefixLength, maxExpansions, transpositions, context);
552+
Query indexQuery = super.fuzzyQuery(value, fuzziness, prefixLength, maxExpansions, transpositions, method, context);
553553
Query dvQuery = super.fuzzyQuery(
554554
value,
555555
fuzziness,

server/src/main/java/org/opensearch/index/mapper/StringFieldType.java

+30
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
import java.util.regex.Pattern;
5656

5757
import static org.opensearch.search.SearchService.ALLOW_EXPENSIVE_QUERIES;
58+
import static org.apache.lucene.search.FuzzyQuery.defaultRewriteMethod;
5859

5960
/** Base class for {@link MappedFieldType} implementations that use the same
6061
* representation for internal index terms as the external representation so
@@ -102,6 +103,35 @@ public Query fuzzyQuery(
102103
);
103104
}
104105

106+
@Override
107+
public Query fuzzyQuery(
108+
Object value,
109+
Fuzziness fuzziness,
110+
int prefixLength,
111+
int maxExpansions,
112+
boolean transpositions,
113+
MultiTermQuery.RewriteMethod method,
114+
QueryShardContext context
115+
) {
116+
if (!context.allowExpensiveQueries()) {
117+
throw new OpenSearchException(
118+
"[fuzzy] queries cannot be executed when '" + ALLOW_EXPENSIVE_QUERIES.getKey() + "' is set to false."
119+
);
120+
}
121+
failIfNotIndexed();
122+
if (method == null) {
123+
method = defaultRewriteMethod(maxExpansions);
124+
}
125+
return new FuzzyQuery(
126+
new Term(name(), indexedValueForSearch(value)),
127+
fuzziness.asDistance(BytesRefs.toString(value)),
128+
prefixLength,
129+
maxExpansions,
130+
transpositions,
131+
method
132+
);
133+
}
134+
105135
@Override
106136
public Query prefixQuery(String value, MultiTermQuery.RewriteMethod method, boolean caseInsensitive, QueryShardContext context) {
107137
if (context.allowExpensiveQueries() == false) {

server/src/main/java/org/opensearch/index/query/FuzzyQueryBuilder.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,7 @@ protected Query doToQuery(QueryShardContext context) throws IOException {
357357
throw new IllegalStateException("Rewrite first");
358358
}
359359
String rewrite = this.rewrite;
360-
Query query = fieldType.fuzzyQuery(value, fuzziness, prefixLength, maxExpansions, transpositions, context);
360+
Query query = fieldType.fuzzyQuery(value, fuzziness, prefixLength, maxExpansions, transpositions, null, context);
361361
if (query instanceof MultiTermQuery) {
362362
MultiTermQuery.RewriteMethod rewriteMethod = QueryParsers.parseRewriteMethod(rewrite, null, LoggingDeprecationHandler.INSTANCE);
363363
QueryParsers.setRewriteMethod((MultiTermQuery) query, rewriteMethod);

server/src/test/java/org/opensearch/index/mapper/KeywordFieldTypeTests.java

+5-2
Original file line numberDiff line numberDiff line change
@@ -263,8 +263,11 @@ public void testRegexpQuery() {
263263
public void testFuzzyQuery() {
264264
MappedFieldType ft = new KeywordFieldType("field");
265265
assertEquals(
266-
new FuzzyQuery(new Term("field", "foo"), 2, 1, 50, true),
267-
ft.fuzzyQuery("foo", Fuzziness.fromEdits(2), 1, 50, true, MOCK_QSC)
266+
new IndexOrDocValuesQuery(
267+
new FuzzyQuery(new Term("field", "foo"), 2, 1, 50, true),
268+
new FuzzyQuery(new Term("field", "foo"), 2, 1, 50, true, MultiTermQuery.DOC_VALUES_REWRITE)
269+
),
270+
ft.fuzzyQuery("foo", Fuzziness.fromEdits(2), 1, 50, true, null, MOCK_QSC)
268271
);
269272

270273
Query indexExpected = new FuzzyQuery(new Term("field", "foo"), 2, 1, 50, true);

0 commit comments

Comments
 (0)