Skip to content

Commit 149d559

Browse files
committed
support termQueryCaseInsensitive/termQuery can search from doc_value in flat_object/keyword field
Signed-off-by: kkewwei <kewei.11@bytedance.com> Signed-off-by: kkewwei <kkewwei@163.com>
1 parent e7e19f7 commit 149d559

File tree

6 files changed

+435
-42
lines changed

6 files changed

+435
-42
lines changed

rest-api-spec/src/main/resources/rest-api-spec/test/index/92_flat_object_support_doc_values.yml

+49-1
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ setup:
4545
{"order":"order7","issue":{"labels":{"number":7,"name":"abc7","status":1}}}
4646
{"index":{"_index":"flat_object_doc_values_test","_id":"8"}}
4747
{"order":"order8","issue":{"labels":{"number":8,"name":"abc8","status":1}}}
48+
{"index":{"_index":"flat_object_doc_values_test","_id":"9"}}
49+
{"order":"order9","issue":{"labels":{"number":9,"name":"abC8","status":1}}}
4850
4951
---
5052
# Delete Index when connection is teardown
@@ -68,7 +70,53 @@ teardown:
6870
}
6971
}
7072

71-
- length: { hits.hits: 9 }
73+
- length: { hits.hits: 10 }
74+
75+
# Case Insensitive Term Query with exact dot path.
76+
- do:
77+
search:
78+
body: {
79+
_source: true,
80+
query: {
81+
bool: {
82+
must: [
83+
{
84+
term: {
85+
issue.labels.name: {
86+
value: "abc8",
87+
case_insensitive: "true"
88+
}
89+
}
90+
}
91+
]
92+
}
93+
}
94+
}
95+
96+
- length: { hits.hits: 2 }
97+
98+
# Case Insensitive Term Query with no path.
99+
- do:
100+
search:
101+
body: {
102+
_source: true,
103+
query: {
104+
bool: {
105+
must: [
106+
{
107+
term: {
108+
issue.labels: {
109+
value: "abc8",
110+
case_insensitive: "true"
111+
}
112+
}
113+
}
114+
]
115+
}
116+
}
117+
}
118+
119+
- length: { hits.hits: 2 }
72120

73121
# Term Query with exact dot path.
74122
- do:

rest-api-spec/src/main/resources/rest-api-spec/test/search/340_doc_values_field.yml

+33-2
Original file line numberDiff line numberDiff line change
@@ -1121,8 +1121,8 @@
11211121
"search on fields with only doc_values enabled":
11221122
- skip:
11231123
features: [ "headers" ]
1124-
version: " - 2.18.99"
1125-
reason: "searching with only doc_values was finally added in 2.19.0"
1124+
version: " - 2.99.99"
1125+
reason: "searching with only doc_values was finally added in 3.00.0"
11261126
- do:
11271127
indices.create:
11281128
index: test-doc-values
@@ -1193,6 +1193,37 @@
11931193
- '{ "some_keyword": "400", "byte": 121, "double": 101.0, "float": "801.0", "half_float": "401.0", "integer": 1291, "long": 13457, "short": 151, "unsigned_long": 10223372036854775801, "ip_field": "192.168.0.2", "boolean": true, "date_nanos": "2020-10-29T12:12:12.123456789Z", "date": "2020-10-29T12:12:12.987Z" }'
11941194
- '{ "index": { "_index": "test-doc-values", "_id": "3" } }'
11951195
- '{ "some_keyword": "5", "byte": 122, "double": 102.0, "float": "802.0", "half_float": "402.0", "integer": 1292, "long": 13458, "short": 152, "unsigned_long": 10223372036854775802, "ip_field": "192.168.0.3", "boolean": false, "date_nanos": "2024-10-29T12:12:12.123456789Z", "date": "2024-10-29T12:12:12.987Z" }'
1196+
- '{ "index": { "_index": "test-doc-values", "_id": "4" } }'
1197+
- '{ "some_keyword": "Keyword1" }'
1198+
- '{ "index": { "_index": "test-doc-values", "_id": "5" } }'
1199+
- '{ "some_keyword": "keyword1" }'
1200+
1201+
- do:
1202+
search:
1203+
rest_total_hits_as_int: true
1204+
index: test-doc-values
1205+
body:
1206+
query:
1207+
term: {
1208+
"some_keyword": {
1209+
"value": "Keyword1"
1210+
} }
1211+
1212+
- match: { hits.total: 1 }
1213+
1214+
- do:
1215+
search:
1216+
rest_total_hits_as_int: true
1217+
index: test-doc-values
1218+
body:
1219+
query:
1220+
term: {
1221+
"some_keyword": {
1222+
"value": "keyword1",
1223+
"case_insensitive": "true"
1224+
} }
1225+
1226+
- match: { hits.total: 2 }
11961227

11971228
- do:
11981229
search:

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

+6-13
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
import org.apache.lucene.document.SortedSetDocValuesField;
1616
import org.apache.lucene.index.IndexOptions;
1717
import org.apache.lucene.index.Term;
18-
import org.apache.lucene.search.BoostQuery;
1918
import org.apache.lucene.search.FieldExistsQuery;
2019
import org.apache.lucene.search.MultiTermQuery;
2120
import org.apache.lucene.search.Query;
@@ -364,23 +363,17 @@ private KeywordFieldType valueFieldType() {
364363
return (mappedFieldTypeName == null) ? valueFieldType : valueAndPathFieldType;
365364
}
366365

366+
@Override
367+
public Query termQueryCaseInsensitive(Object value, QueryShardContext context) {
368+
return valueFieldType().termQueryCaseInsensitive(rewriteValue(inputToString(value)), context);
369+
}
370+
367371
/**
368372
* redirect queries with rewrite value to rewriteSearchValue and directSubFieldName
369373
*/
370374
@Override
371375
public Query termQuery(Object value, @Nullable QueryShardContext context) {
372-
373-
String searchValueString = inputToString(value);
374-
String directSubFieldName = directSubfield();
375-
String rewriteSearchValue = rewriteValue(searchValueString);
376-
377-
failIfNotIndexed();
378-
Query query;
379-
query = new TermQuery(new Term(directSubFieldName, indexedValueForSearch(rewriteSearchValue)));
380-
if (boost() != 1f) {
381-
query = new BoostQuery(query, boost());
382-
}
383-
return query;
376+
return valueFieldType().termQuery(rewriteValue(inputToString(value)), context);
384377
}
385378

386379
@Override

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

+41
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import org.apache.lucene.document.SortedSetDocValuesField;
4040
import org.apache.lucene.index.IndexOptions;
4141
import org.apache.lucene.index.Term;
42+
import org.apache.lucene.search.BoostQuery;
4243
import org.apache.lucene.search.FuzzyQuery;
4344
import org.apache.lucene.search.IndexOrDocValuesQuery;
4445
import org.apache.lucene.search.MultiTermQuery;
@@ -398,6 +399,46 @@ protected Object rewriteForDocValue(Object value) {
398399
return value;
399400
}
400401

402+
@Override
403+
public Query termQueryCaseInsensitive(Object value, QueryShardContext context) {
404+
failIfNotIndexedAndNoDocValues();
405+
if (isSearchable()) {
406+
return super.termQueryCaseInsensitive(value, context);
407+
} else {
408+
BytesRef bytesRef = indexedValueForSearch(rewriteForDocValue(value));
409+
Term term = new Term(name(), bytesRef);
410+
Query query = AutomatonQueries.createAutomatonQuery(
411+
term,
412+
AutomatonQueries.toCaseInsensitiveString(bytesRef.utf8ToString(), Integer.MAX_VALUE),
413+
MultiTermQuery.DOC_VALUES_REWRITE
414+
);
415+
if (boost() != 1f) {
416+
query = new BoostQuery(query, boost());
417+
}
418+
return query;
419+
}
420+
}
421+
422+
@Override
423+
public Query termQuery(Object value, QueryShardContext context) {
424+
failIfNotIndexedAndNoDocValues();
425+
if (isSearchable()) {
426+
return super.termQuery(value, context);
427+
} else {
428+
Query query = SortedSetDocValuesField.newSlowRangeQuery(
429+
name(),
430+
indexedValueForSearch(rewriteForDocValue(value)),
431+
indexedValueForSearch(rewriteForDocValue(value)),
432+
true,
433+
true
434+
);
435+
if (boost() != 1f) {
436+
query = new BoostQuery(query, boost());
437+
}
438+
return query;
439+
}
440+
}
441+
401442
@Override
402443
public Query termsQuery(List<?> values, QueryShardContext context) {
403444
failIfNotIndexedAndNoDocValues();

0 commit comments

Comments
 (0)