Skip to content

Commit af364df

Browse files
elasticsearchmachineromseygeek
authored andcommitted
[7.14] Call fixRedundantIncludes on dynamic mapping updates (#74903) (#74918)
Dynamic mappings updates containing nested mappings were not fixing their redundant include settings before being posted back to the put mappings service; this meant that a dynamic mapping that had both 'include_in_parent' and 'include_in_root' set to 'true' could cause an error if it was returned from multiple shards, because the first mapping would be updated to have 'include_in_root' set to 'false' when merged, and merging this with the second mapping with 'include_in_root' set to 'true' would cause a conflict. This commit ensures that fixRedundantIncludes is called on dynamic mappings before they are posted back to the mapping service. Fixes #74899
1 parent 5ddaed9 commit af364df

File tree

2 files changed

+69
-0
lines changed

2 files changed

+69
-0
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,7 @@ static Mapping createDynamicUpdate(MappingLookup mappingLookup,
277277
RootObjectMapper root;
278278
if (dynamicMappers.isEmpty() == false) {
279279
root = createDynamicUpdate(mappingLookup, dynamicMappers);
280+
root.fixRedundantIncludes();
280281
} else {
281282
root = mappingLookup.getMapping().getRoot().copyAndReset();
282283
}

server/src/test/java/org/elasticsearch/index/mapper/NestedObjectMapperTests.java

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,44 @@ public void testMultipleLevelsIncludeRoot1() throws Exception {
412412
assertThat(fields.size(), equalTo(new HashSet<>(fields).size()));
413413
}
414414

415+
public void testRecursiveIncludeInParent() throws IOException {
416+
417+
// if we have a nested hierarchy, and all nested mappers have 'include_in_parent'
418+
// set to 'true', then values from the grandchild nodes should be copied all the
419+
// way up the hierarchy and into the root document, even if 'include_in_root' has
420+
// explicitly been set to 'false'.
421+
422+
MapperService mapperService = createMapperService(mapping(b -> {
423+
b.startObject("nested1");
424+
b.field("type", "nested");
425+
b.field("include_in_parent", true);
426+
b.field("include_in_root", false);
427+
b.startObject("properties");
428+
b.startObject("nested1_id").field("type", "keyword").endObject();
429+
b.startObject("nested2");
430+
b.field("type", "nested");
431+
b.field("include_in_parent", true);
432+
b.field("include_in_root", false);
433+
b.startObject("properties");
434+
b.startObject("nested2_id").field("type", "keyword").endObject();
435+
b.endObject();
436+
b.endObject();
437+
b.endObject();
438+
b.endObject();
439+
}));
440+
441+
ParsedDocument doc = mapperService.documentMapper().parse(source(b -> {
442+
b.startObject("nested1");
443+
b.field("nested1_id", "1");
444+
b.startObject("nested2");
445+
b.field("nested2_id", "2");
446+
b.endObject();
447+
b.endObject();
448+
}));
449+
450+
assertNotNull(doc.rootDoc().getField("nested1.nested2.nested2_id"));
451+
}
452+
415453
/**
416454
* Same as {@link NestedObjectMapperTests#testMultipleLevelsIncludeRoot1()} but tests for the
417455
* case where the transitive {@code include_in_parent} and redundant {@code include_in_root}
@@ -807,4 +845,34 @@ public void testMergeNestedMappings() throws IOException {
807845
})));
808846
assertEquals("the [include_in_root] parameter can't be updated on a nested object mapping", e2.getMessage());
809847
}
848+
849+
public void testMergeNestedMappingsFromDynamicUpdate() throws IOException {
850+
851+
// Check that dynamic mappings have redundant includes removed
852+
853+
MapperService mapperService = createMapperService(topMapping(b -> {
854+
b.startArray("dynamic_templates");
855+
b.startObject();
856+
b.startObject("object_fields");
857+
b.field("match_mapping_type", "object");
858+
b.startObject("mapping");
859+
b.field("type", "nested");
860+
b.field("include_in_parent", true);
861+
b.field("include_in_root", true);
862+
b.endObject();
863+
b.field("match", "*");
864+
b.endObject();
865+
b.endObject();
866+
b.endArray();
867+
}));
868+
869+
ParsedDocument doc = mapperService.documentMapper().parse(source(b -> b.startObject("object").endObject()));
870+
871+
merge("_doc", mapperService, Strings.toString(doc.dynamicMappingsUpdate()));
872+
merge("_doc", mapperService, Strings.toString(doc.dynamicMappingsUpdate()));
873+
874+
assertThat(
875+
Strings.toString(mapperService.documentMapper().mapping()),
876+
containsString("\"properties\":{\"object\":{\"type\":\"nested\",\"include_in_parent\":true}}"));
877+
}
810878
}

0 commit comments

Comments
 (0)