Skip to content

Commit b4a3784

Browse files
romseygeekelasticsearchmachine
authored and
elasticsearchmachine
committed
Call fixRedundantIncludes on dynamic mapping updates (elastic#74903)
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 elastic#74899
1 parent 13f0284 commit b4a3784

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
@@ -262,6 +262,7 @@ static Mapping createDynamicUpdate(MappingLookup mappingLookup,
262262
RootObjectMapper root;
263263
if (dynamicMappers.isEmpty() == false) {
264264
root = createDynamicUpdate(mappingLookup, dynamicMappers);
265+
root.fixRedundantIncludes();
265266
} else {
266267
root = mappingLookup.getMapping().getRoot().copyAndReset();
267268
}

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}
@@ -869,4 +907,34 @@ public void testMergeNestedMappings() throws IOException {
869907
})));
870908
assertEquals("the [include_in_root] parameter can't be updated on a nested object mapping", e2.getMessage());
871909
}
910+
911+
public void testMergeNestedMappingsFromDynamicUpdate() throws IOException {
912+
913+
// Check that dynamic mappings have redundant includes removed
914+
915+
MapperService mapperService = createMapperService(topMapping(b -> {
916+
b.startArray("dynamic_templates");
917+
b.startObject();
918+
b.startObject("object_fields");
919+
b.field("match_mapping_type", "object");
920+
b.startObject("mapping");
921+
b.field("type", "nested");
922+
b.field("include_in_parent", true);
923+
b.field("include_in_root", true);
924+
b.endObject();
925+
b.field("match", "*");
926+
b.endObject();
927+
b.endObject();
928+
b.endArray();
929+
}));
930+
931+
ParsedDocument doc = mapperService.documentMapper().parse(source(b -> b.startObject("object").endObject()));
932+
933+
merge(mapperService, Strings.toString(doc.dynamicMappingsUpdate()));
934+
merge(mapperService, Strings.toString(doc.dynamicMappingsUpdate()));
935+
936+
assertThat(
937+
Strings.toString(mapperService.documentMapper().mapping()),
938+
containsString("\"properties\":{\"object\":{\"type\":\"nested\",\"include_in_parent\":true}}"));
939+
}
872940
}

0 commit comments

Comments
 (0)