diff --git a/CHANGELOG.md b/CHANGELOG.md index 20e6c03d5a9d6..c152a4756c935 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -95,6 +95,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - Fix Shallow copy snapshot failures on closed index ([#16868](https://github.com/opensearch-project/OpenSearch/pull/16868)) - Fix multi-value sort for unsigned long ([#16732](https://github.com/opensearch-project/OpenSearch/pull/16732)) - The `phone-search` analyzer no longer emits the tel/sip prefix, international calling code, extension numbers and unformatted input as a token ([#16993](https://github.com/opensearch-project/OpenSearch/pull/16993)) +- Fix exists queries on nested flat_object fields throws exception ([#16803](https://github.com/opensearch-project/OpenSearch/pull/16803)) ### Security diff --git a/rest-api-spec/src/main/resources/rest-api-spec/test/index/90_flat_object.yml b/rest-api-spec/src/main/resources/rest-api-spec/test/index/90_flat_object.yml index 2a469aa5ff04d..5a1791ede6d5b 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/test/index/90_flat_object.yml +++ b/rest-api-spec/src/main/resources/rest-api-spec/test/index/90_flat_object.yml @@ -73,6 +73,26 @@ teardown: - do: indices.delete: index: test + +--- +"Exist query in root field": + - skip: + version: "- 2.99.99" + reason: "the query would throw exception prior to 2.99.99" + + - do: + search: + body: { + _source: true, + size: 10, + query: { + exists: { + field: "catalog" + } + } + } + - length: { hits.hits: 2 } + --- "Invalid docs": - skip: diff --git a/server/src/main/java/org/opensearch/index/mapper/FlatObjectFieldMapper.java b/server/src/main/java/org/opensearch/index/mapper/FlatObjectFieldMapper.java index 4fe821ff74d34..ea3ff0d890c6e 100644 --- a/server/src/main/java/org/opensearch/index/mapper/FlatObjectFieldMapper.java +++ b/server/src/main/java/org/opensearch/index/mapper/FlatObjectFieldMapper.java @@ -28,6 +28,7 @@ import org.opensearch.common.xcontent.JsonToStringXContentParser; import org.opensearch.core.common.ParsingException; import org.opensearch.core.common.io.stream.StreamOutput; +import org.opensearch.core.common.Strings; import org.opensearch.core.xcontent.DeprecationHandler; import org.opensearch.core.xcontent.NamedXContentRegistry; import org.opensearch.core.xcontent.XContentParser; @@ -87,7 +88,7 @@ public static class Defaults { @Override public MappedFieldType keyedFieldType(String key) { return new FlatObjectFieldType( - this.name() + DOT_SYMBOL + key, + Strings.isNullOrEmpty(key) ? this.name() : (this.name() + DOT_SYMBOL + key), this.name(), (KeywordFieldType) valueFieldMapper.fieldType(), (KeywordFieldType) valueAndPathFieldMapper.fieldType() diff --git a/server/src/test/java/org/opensearch/index/mapper/FlatObjectFieldMapperTests.java b/server/src/test/java/org/opensearch/index/mapper/FlatObjectFieldMapperTests.java index 7e6aa00c87290..1f8698ab90a6a 100644 --- a/server/src/test/java/org/opensearch/index/mapper/FlatObjectFieldMapperTests.java +++ b/server/src/test/java/org/opensearch/index/mapper/FlatObjectFieldMapperTests.java @@ -16,6 +16,7 @@ import org.apache.lucene.search.Query; import org.apache.lucene.search.TermQuery; import org.apache.lucene.util.BytesRef; +import org.opensearch.common.util.set.Sets; import org.opensearch.common.xcontent.XContentFactory; import org.opensearch.common.xcontent.json.JsonXContent; import org.opensearch.core.xcontent.ToXContent; @@ -24,6 +25,7 @@ import org.opensearch.search.DocValueFormat; import java.io.IOException; +import java.util.Set; import static org.opensearch.common.xcontent.JsonToStringXContentParser.VALUE_AND_PATH_SUFFIX; import static org.opensearch.common.xcontent.JsonToStringXContentParser.VALUE_SUFFIX; @@ -416,7 +418,14 @@ public void testFetchDocValues() throws IOException { Throwable throwable = assertThrows(IllegalArgumentException.class, () -> ft.docValueFormat(null, null)); assertEquals("Field [field] of type [flat_object] does not support doc_value in root field", throwable.getMessage()); } + } + public void testPatternMatch() throws IOException { + MapperService mapperService = createMapperService(fieldMapping(this::minimalMapping)); + QueryShardContext queryShardContext = createQueryShardContext(mapperService); + Set fields = queryShardContext.simpleMatchToIndexNames("field.*"); + assertEquals(2, fields.size()); + assertEquals(Sets.newHashSet("field._value", "field._valueAndPath"), fields); } @Override