Skip to content

Commit 60829d2

Browse files
handling edge cases
Signed-off-by: bharath-techie <bharath78910@gmail.com>
1 parent b1f8fba commit 60829d2

File tree

4 files changed

+149
-4
lines changed

4 files changed

+149
-4
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
2424
- Added a precaution to handle extreme date values during sorting to prevent `arithmetic_exception: long overflow` ([#16812](https://github.com/opensearch-project/OpenSearch/pull/16812)).
2525
- Add search replica stats to segment replication stats API ([#16678](https://github.com/opensearch-project/OpenSearch/pull/16678))
2626
- Introduce a setting to disable download of full cluster state from remote on term mismatch([#16798](https://github.com/opensearch-project/OpenSearch/pull/16798/))
27+
- Changes to support IP field in star tree indexing([#16641](https://github.com/opensearch-project/OpenSearch/pull/16641/))
28+
- Support object fields in star-tree index([#16728](https://github.com/opensearch-project/OpenSearch/pull/16728/))
2729

2830
### Dependencies
2931
- Bump `com.google.cloud:google-cloud-core-http` from 2.23.0 to 2.47.0 ([#16504](https://github.com/opensearch-project/OpenSearch/pull/16504))

server/src/internalClusterTest/java/org/opensearch/index/mapper/StarTreeMapperIT.java

+131-1
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,98 @@ private static XContentBuilder createNestedTestMapping() {
205205
}
206206
}
207207

208+
private static XContentBuilder createNestedTestMappingForArray() {
209+
try {
210+
return jsonBuilder().startObject()
211+
.startObject("composite")
212+
.startObject("startree-1")
213+
.field("type", "star_tree")
214+
.startObject("config")
215+
.startObject("date_dimension")
216+
.field("name", "timestamp")
217+
.endObject()
218+
.startArray("ordered_dimensions")
219+
.startObject()
220+
.field("name", "status")
221+
.endObject()
222+
.startObject()
223+
.field("name", "nested.nested1.keyword_dv")
224+
.endObject()
225+
.endArray()
226+
.startArray("metrics")
227+
.startObject()
228+
.field("name", "nested3.numeric_dv")
229+
.endObject()
230+
.endArray()
231+
.endObject()
232+
.endObject()
233+
.endObject()
234+
.startObject("properties")
235+
.startObject("timestamp")
236+
.field("type", "date")
237+
.endObject()
238+
.startObject("status")
239+
.field("type", "integer")
240+
.endObject()
241+
.startObject("nested3")
242+
.startObject("properties")
243+
.startObject("numeric_dv")
244+
.field("type", "integer")
245+
.field("doc_values", true)
246+
.endObject()
247+
.endObject()
248+
.endObject()
249+
.startObject("numeric")
250+
.field("type", "integer")
251+
.field("doc_values", false)
252+
.endObject()
253+
.startObject("nested")
254+
.startObject("properties")
255+
.startObject("nested1")
256+
.startObject("properties")
257+
.startObject("status")
258+
.field("type", "integer")
259+
.field("doc_values", true)
260+
.endObject()
261+
.startObject("keyword_dv")
262+
.field("type", "keyword")
263+
.field("doc_values", true)
264+
.endObject()
265+
.endObject()
266+
.endObject()
267+
.endObject()
268+
.endObject()
269+
.startObject("nested-not-startree")
270+
.startObject("properties")
271+
.startObject("nested1")
272+
.startObject("properties")
273+
.startObject("status")
274+
.field("type", "integer")
275+
.field("doc_values", true)
276+
.endObject()
277+
.startObject("keyword_dv")
278+
.field("type", "keyword")
279+
.field("doc_values", true)
280+
.endObject()
281+
.endObject()
282+
.endObject()
283+
.endObject()
284+
.endObject()
285+
.startObject("keyword")
286+
.field("type", "keyword")
287+
.field("doc_values", false)
288+
.endObject()
289+
.startObject("ip")
290+
.field("type", "ip")
291+
.field("doc_values", false)
292+
.endObject()
293+
.endObject()
294+
.endObject();
295+
} catch (IOException e) {
296+
throw new IllegalStateException(e);
297+
}
298+
}
299+
208300
private static XContentBuilder createDateTestMapping(boolean duplicate) {
209301
try {
210302
return jsonBuilder().startObject()
@@ -693,6 +785,7 @@ public void testCompositeIndexWithArraysInCompositeField() throws IOException {
693785
}
694786

695787
public void testCompositeIndexWithArraysInNestedCompositeField() throws IOException {
788+
// here nested.nested1.status is part of the composite field but "nested" field itself is an array
696789
prepareCreate(TEST_INDEX).setSettings(settings).setMapping(createNestedTestMapping()).get();
697790
// Attempt to index a document with an array field
698791
XContentBuilder doc = jsonBuilder().startObject()
@@ -726,7 +819,7 @@ public void testCompositeIndexWithArraysInNestedCompositeField() throws IOExcept
726819

727820
public void testCompositeIndexWithArraysInChildNestedCompositeField() throws IOException {
728821
prepareCreate(TEST_INDEX).setSettings(settings).setMapping(createNestedTestMapping()).get();
729-
// Attempt to index a document with an array field
822+
// here nested.nested1.status is part of the composite field but "nested.nested1" field is an array
730823
XContentBuilder doc = jsonBuilder().startObject()
731824
.field("timestamp", "2023-06-01T12:00:00Z")
732825
.startObject("nested")
@@ -754,6 +847,43 @@ public void testCompositeIndexWithArraysInChildNestedCompositeField() throws IOE
754847
);
755848
}
756849

850+
public void testCompositeIndexWithArraysInNestedCompositeFieldSameNameAsNormalField() throws IOException {
851+
prepareCreate(TEST_INDEX).setSettings(settings).setMapping(createNestedTestMappingForArray()).get();
852+
// here status is part of the composite field but "nested.nested1.status" field is an array which is not
853+
// part of composite field
854+
XContentBuilder doc = jsonBuilder().startObject()
855+
.field("timestamp", "2023-06-01T12:00:00Z")
856+
.startObject("nested")
857+
.startObject("nested1")
858+
.startArray("status")
859+
.value(10)
860+
.value(20)
861+
.value(30)
862+
.endArray()
863+
.endObject()
864+
.endObject()
865+
.field("status", "200")
866+
.endObject();
867+
// Index the document and refresh
868+
// Index the document and refresh
869+
IndexResponse indexResponse = client().prepareIndex(TEST_INDEX).setSource(doc).get();
870+
871+
assertEquals(RestStatus.CREATED, indexResponse.status());
872+
873+
client().admin().indices().prepareRefresh(TEST_INDEX).get();
874+
// Verify the document was indexed
875+
SearchResponse searchResponse = client().prepareSearch(TEST_INDEX).setQuery(QueryBuilders.matchAllQuery()).get();
876+
877+
assertEquals(1, searchResponse.getHits().getTotalHits().value);
878+
879+
// Verify the values in the indexed document
880+
SearchHit hit = searchResponse.getHits().getAt(0);
881+
assertEquals("2023-06-01T12:00:00Z", hit.getSourceAsMap().get("timestamp"));
882+
883+
int values = Integer.parseInt((String) hit.getSourceAsMap().get("status"));
884+
assertEquals(200, values);
885+
}
886+
757887
public void testCompositeIndexWithNestedArraysInNonCompositeField() throws IOException {
758888
prepareCreate(TEST_INDEX).setSettings(settings).setMapping(createNestedTestMapping()).get();
759889
// Attempt to index a document with an array field

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

+10-2
Original file line numberDiff line numberDiff line change
@@ -661,10 +661,18 @@ private static void parseNonDynamicArray(ParseContext context, ObjectMapper mapp
661661
throws IOException {
662662
XContentParser parser = context.parser();
663663
XContentParser.Token token;
664+
String path = context.path().pathAsText(arrayFieldName);
665+
boolean isNested = path.contains(".") || context.mapperService().isCompositeIndexFieldNestedField(path);
664666
// block array values for composite index fields
667+
// Assume original index has 2 fields - status , nested.nested1.status
668+
// case 1 : if status is part of composite index and nested.nested1.status is not part of composite index,
669+
// then nested.nested1.status/nested.nested1/nested array should not be blocked
670+
// case 2 : if nested.nested1.status is part of composite index and status is not part of composite index,
671+
// then arrays in nested/nested.nested1 and nested.nested1.status fields should be blocked
672+
// but arrays in status should not be blocked
665673
if (context.indexSettings().isCompositeIndex()
666-
&& (context.mapperService().isFieldPartOfCompositeIndex(arrayFieldName)
667-
|| context.mapperService().isFieldPartOfCompositeIndex(context.path().pathAsText(arrayFieldName)))) {
674+
&& ((isNested == false && context.mapperService().isFieldPartOfCompositeIndex(arrayFieldName))
675+
|| (isNested && context.mapperService().isCompositeIndexFieldNestedField(path)))) {
668676
throw new MapperParsingException(
669677
String.format(
670678
Locale.ROOT,

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

+6-1
Original file line numberDiff line numberDiff line change
@@ -707,7 +707,12 @@ private Set<CompositeMappedFieldType> getCompositeFieldTypesFromMapper() {
707707
}
708708

709709
public boolean isFieldPartOfCompositeIndex(String field) {
710-
return fieldsPartOfCompositeMappings.contains(field) || nestedFieldsPartOfCompositeMappings.contains(field);
710+
return fieldsPartOfCompositeMappings.contains(field);
711+
}
712+
713+
public boolean isCompositeIndexFieldNestedField(String field) {
714+
return nestedFieldsPartOfCompositeMappings.contains(field);
715+
711716
}
712717

713718
public ObjectMapper getObjectMapper(String name) {

0 commit comments

Comments
 (0)