diff --git a/docs/changelog/110833.yaml b/docs/changelog/110833.yaml new file mode 100644 index 0000000000000..008fc489ed731 --- /dev/null +++ b/docs/changelog/110833.yaml @@ -0,0 +1,5 @@ +pr: 110833 +summary: Make empty string searches be consistent with case (in)sensitivity +area: Search +type: bug +issues: [] diff --git a/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/search/171_term_query.yml b/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/search/171_term_query.yml new file mode 100644 index 0000000000000..5ab65b0c69e8a --- /dev/null +++ b/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/search/171_term_query.yml @@ -0,0 +1,37 @@ +--- +"case insensitive term query on blank keyword is consistent": + - requires: + cluster_features: [ "gte_v8.16.0" ] + reason: "query consistency bug fix in 8.16.0" + - do: + indices.create: + index: index_with_blank_keyword + body: + settings: + number_of_shards: 1 + mappings: + properties: + keyword_field: + type: keyword + - do: + bulk: + refresh: true + body: + - '{"index": {"_index": "index_with_blank_keyword", "_id": "1"}}' + - '{"keyword_field": ""}' + + - do: + search: + rest_total_hits_as_int: true + index: index_with_blank_keyword + body: {"query" : {"term" : {"keyword_field" : {"value": ""}}}} + + - match: { hits.total: 1 } + + - do: + search: + rest_total_hits_as_int: true + index: index_with_blank_keyword + body: { "query": { "term": { "keyword_field": {"value": "", "case_insensitive": true } } } } + + - match: { hits.total: 1 } diff --git a/server/src/main/java/org/elasticsearch/index/mapper/TermBasedFieldType.java b/server/src/main/java/org/elasticsearch/index/mapper/TermBasedFieldType.java index 80e6d04d967d5..f574e509df9b9 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/TermBasedFieldType.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/TermBasedFieldType.java @@ -45,7 +45,13 @@ protected BytesRef indexedValueForSearch(Object value) { @Override public Query termQueryCaseInsensitive(Object value, SearchExecutionContext context) { failIfNotIndexed(); - return AutomatonQueries.caseInsensitiveTermQuery(new Term(name(), indexedValueForSearch(value))); + final BytesRef valueForSearch = indexedValueForSearch(value); + // check if valueForSearch is the same as an empty string + // if we have a length of zero, just do a regular term query + if (valueForSearch.length == 0) { + return termQuery(value, context); + } + return AutomatonQueries.caseInsensitiveTermQuery(new Term(name(), valueForSearch)); } @Override