Skip to content

Commit

Permalink
[7.14] Call fixRedundantIncludes on dynamic mapping updates (#74903) (#…
Browse files Browse the repository at this point in the history
…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
  • Loading branch information
elasticsearchmachine authored and romseygeek committed Jul 5, 2021
1 parent 5ddaed9 commit af364df
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,7 @@ static Mapping createDynamicUpdate(MappingLookup mappingLookup,
RootObjectMapper root;
if (dynamicMappers.isEmpty() == false) {
root = createDynamicUpdate(mappingLookup, dynamicMappers);
root.fixRedundantIncludes();
} else {
root = mappingLookup.getMapping().getRoot().copyAndReset();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,44 @@ public void testMultipleLevelsIncludeRoot1() throws Exception {
assertThat(fields.size(), equalTo(new HashSet<>(fields).size()));
}

public void testRecursiveIncludeInParent() throws IOException {

// if we have a nested hierarchy, and all nested mappers have 'include_in_parent'
// set to 'true', then values from the grandchild nodes should be copied all the
// way up the hierarchy and into the root document, even if 'include_in_root' has
// explicitly been set to 'false'.

MapperService mapperService = createMapperService(mapping(b -> {
b.startObject("nested1");
b.field("type", "nested");
b.field("include_in_parent", true);
b.field("include_in_root", false);
b.startObject("properties");
b.startObject("nested1_id").field("type", "keyword").endObject();
b.startObject("nested2");
b.field("type", "nested");
b.field("include_in_parent", true);
b.field("include_in_root", false);
b.startObject("properties");
b.startObject("nested2_id").field("type", "keyword").endObject();
b.endObject();
b.endObject();
b.endObject();
b.endObject();
}));

ParsedDocument doc = mapperService.documentMapper().parse(source(b -> {
b.startObject("nested1");
b.field("nested1_id", "1");
b.startObject("nested2");
b.field("nested2_id", "2");
b.endObject();
b.endObject();
}));

assertNotNull(doc.rootDoc().getField("nested1.nested2.nested2_id"));
}

/**
* Same as {@link NestedObjectMapperTests#testMultipleLevelsIncludeRoot1()} but tests for the
* case where the transitive {@code include_in_parent} and redundant {@code include_in_root}
Expand Down Expand Up @@ -807,4 +845,34 @@ public void testMergeNestedMappings() throws IOException {
})));
assertEquals("the [include_in_root] parameter can't be updated on a nested object mapping", e2.getMessage());
}

public void testMergeNestedMappingsFromDynamicUpdate() throws IOException {

// Check that dynamic mappings have redundant includes removed

MapperService mapperService = createMapperService(topMapping(b -> {
b.startArray("dynamic_templates");
b.startObject();
b.startObject("object_fields");
b.field("match_mapping_type", "object");
b.startObject("mapping");
b.field("type", "nested");
b.field("include_in_parent", true);
b.field("include_in_root", true);
b.endObject();
b.field("match", "*");
b.endObject();
b.endObject();
b.endArray();
}));

ParsedDocument doc = mapperService.documentMapper().parse(source(b -> b.startObject("object").endObject()));

merge("_doc", mapperService, Strings.toString(doc.dynamicMappingsUpdate()));
merge("_doc", mapperService, Strings.toString(doc.dynamicMappingsUpdate()));

assertThat(
Strings.toString(mapperService.documentMapper().mapping()),
containsString("\"properties\":{\"object\":{\"type\":\"nested\",\"include_in_parent\":true}}"));
}
}

0 comments on commit af364df

Please sign in to comment.