Skip to content

Commit c373ab2

Browse files
author
gesong.samuel
committed
fix case insensitive query on wildcard field
Signed-off-by: gesong.samuel <[email protected]>
1 parent 5642ce7 commit c373ab2

File tree

2 files changed

+48
-8
lines changed

2 files changed

+48
-8
lines changed

rest-api-spec/src/main/resources/rest-api-spec/test/search/270_wildcard_fieldtype_queries.yml

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,12 @@ setup:
5656
id: 6
5757
body:
5858
other_field: "test"
59+
- do:
60+
index:
61+
index: test
62+
id: 7
63+
body:
64+
my_field: "ABCD"
5965
- do:
6066
indices.refresh: {}
6167

@@ -90,8 +96,9 @@ setup:
9096
query:
9197
term:
9298
my_field.lower: "abcd"
93-
- match: { hits.total.value: 1 }
99+
- match: { hits.total.value: 2 }
94100
- match: { hits.hits.0._id: "5" }
101+
- match: { hits.hits.0._id: "7" }
95102

96103
- do:
97104
search:
@@ -100,8 +107,9 @@ setup:
100107
query:
101108
term:
102109
my_field.lower: "ABCD"
103-
- match: { hits.total.value: 1 }
110+
- match: { hits.total.value: 2 }
104111
- match: { hits.hits.0._id: "5" }
112+
- match: { hits.hits.1._id: "7" }
105113

106114
- do:
107115
search:
@@ -215,7 +223,7 @@ setup:
215223
wildcard:
216224
my_field:
217225
value: "*"
218-
- match: { hits.total.value: 5 }
226+
- match: { hits.total.value: 6 }
219227
---
220228
"regexp match-all works":
221229
- do:
@@ -226,7 +234,7 @@ setup:
226234
regexp:
227235
my_field:
228236
value: ".*"
229-
- match: { hits.total.value: 5 }
237+
- match: { hits.total.value: 6 }
230238
---
231239
"terms query on wildcard field matches":
232240
- do:
@@ -237,3 +245,28 @@ setup:
237245
terms: { my_field: ["AbCd"] }
238246
- match: { hits.total.value: 1 }
239247
- match: { hits.hits.0._id: "5" }
248+
---
249+
"case insensitive query on wildcard field":
250+
- do:
251+
search:
252+
index: test
253+
body:
254+
query:
255+
wildcard:
256+
my_field:
257+
value: "AbCd"
258+
- match: { hits.total.value: 1 }
259+
- match: { hits.hits.0._id: "5" }
260+
261+
- do:
262+
search:
263+
index: test
264+
body:
265+
query:
266+
wildcard:
267+
my_field:
268+
value: "AbCd"
269+
case_insensitive: true
270+
- match: { hits.total.value: 2 }
271+
- match: { hits.hits.0._id: "5" }
272+
- match: { hits.hits.1._id: "7" }

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

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
import org.apache.lucene.util.automaton.RegExp;
4141
import org.opensearch.common.lucene.BytesRefs;
4242
import org.opensearch.common.lucene.Lucene;
43+
import org.opensearch.common.lucene.search.AutomatonQueries;
4344
import org.opensearch.common.regex.Regex;
4445
import org.opensearch.common.unit.Fuzziness;
4546
import org.opensearch.core.xcontent.XContentParser;
@@ -460,7 +461,7 @@ public Query wildcardQuery(String value, MultiTermQuery.RewriteMethod method, bo
460461
return existsQuery(context);
461462
}
462463
} else {
463-
approximation = matchAllTermsQuery(name(), requiredNGrams);
464+
approximation = matchAllTermsQuery(name(), requiredNGrams, caseInsensitive);
464465
}
465466
return new WildcardMatchingQuery(name(), approximation, matchPredicate, value, context, this);
466467
}
@@ -650,7 +651,7 @@ public Query termsQuery(List<?> values, QueryShardContext context) {
650651
StringBuilder pattern = new StringBuilder();
651652
for (Object value : values) {
652653
String stringVal = BytesRefs.toString(value);
653-
builder.add(matchAllTermsQuery(name(), getRequiredNGrams(stringVal)), BooleanClause.Occur.SHOULD);
654+
builder.add(matchAllTermsQuery(name(), getRequiredNGrams(stringVal), false), BooleanClause.Occur.SHOULD);
654655
expectedValues.add(stringVal);
655656
if (pattern.length() > 0) {
656657
pattern.append('|');
@@ -660,10 +661,16 @@ public Query termsQuery(List<?> values, QueryShardContext context) {
660661
return new WildcardMatchingQuery(name(), builder.build(), expectedValues::contains, pattern.toString(), context, this);
661662
}
662663

663-
private static BooleanQuery matchAllTermsQuery(String fieldName, Set<String> terms) {
664+
private static BooleanQuery matchAllTermsQuery(String fieldName, Set<String> terms, boolean caseInsensitive) {
664665
BooleanQuery.Builder matchAllTermsBuilder = new BooleanQuery.Builder();
666+
Query query;
665667
for (String term : terms) {
666-
matchAllTermsBuilder.add(new TermQuery(new Term(fieldName, term)), BooleanClause.Occur.FILTER);
668+
if (caseInsensitive) {
669+
query = AutomatonQueries.caseInsensitiveTermQuery(new Term(fieldName, term));
670+
} else {
671+
query = new TermQuery(new Term(fieldName, term));
672+
}
673+
matchAllTermsBuilder.add(query, BooleanClause.Occur.FILTER);
667674
}
668675
return matchAllTermsBuilder.build();
669676
}

0 commit comments

Comments
 (0)