Skip to content

Commit d7cded8

Browse files
Fix updating include_in_parent/include_in_root of nested field. (#55326)
The main changes are: 1. Throw an error when updating `include_in_parent` or `include_in_root` attribute of nested field dynamically by the PUT mapping API. 2. Add a test for the change. Closes #53792 Co-authored-by: bellengao <[email protected]>
1 parent b810f00 commit d7cded8

File tree

3 files changed

+54
-4
lines changed

3 files changed

+54
-4
lines changed

docs/reference/migration/migrate_7_8.asciidoc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,15 @@ Previously, Elasticsearch accepted mapping updates that tried to change the
4141
request didn't throw an error. As of 7.8, requests that attempt to change
4242
`enabled` on the root mapping will fail.
4343

44+
[discrete]
45+
[[prevent-include-in-root-change]]
46+
==== `include_in_root` and `include_in_parent` cannot be changed
47+
48+
Elasticsearch previously accepted mapping updates that changed the
49+
`include_in_root` and `include_in_parent` settings. The update was not
50+
applied, but the request didn't throw an error. As of 7.8, requests that
51+
attempt to change these settings will fail.
52+
4453
[discrete]
4554
[[breaking_78_settings_changes]]
4655
=== Settings changes

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

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -459,9 +459,7 @@ protected void doMerge(final ObjectMapper mergeWith) {
459459
this.dynamic = mergeWith.dynamic;
460460
}
461461

462-
if (isEnabled() != mergeWith.isEnabled()) {
463-
throw new MapperException("The [enabled] parameter can't be updated for the object mapping [" + name() + "].");
464-
}
462+
checkObjectMapperParameters(mergeWith);
465463

466464
for (Mapper mergeWithMapper : mergeWith) {
467465
Mapper mergeIntoMapper = mappers.get(mergeWithMapper.simpleName());
@@ -478,6 +476,22 @@ protected void doMerge(final ObjectMapper mergeWith) {
478476
}
479477
}
480478

479+
private void checkObjectMapperParameters(final ObjectMapper mergeWith) {
480+
if (isEnabled() != mergeWith.isEnabled()) {
481+
throw new MapperException("The [enabled] parameter can't be updated for the object mapping [" + name() + "].");
482+
}
483+
484+
if (nested().isIncludeInParent() != mergeWith.nested().isIncludeInParent()) {
485+
throw new MapperException("The [include_in_parent] parameter can't be updated for the nested object mapping [" +
486+
name() + "].");
487+
}
488+
489+
if (nested().isIncludeInRoot() != mergeWith.nested().isIncludeInRoot()) {
490+
throw new MapperException("The [include_in_root] parameter can't be updated for the nested object mapping [" +
491+
name() + "].");
492+
}
493+
}
494+
481495
@Override
482496
public ObjectMapper updateFieldType(Map<String, MappedFieldType> fullNameToFieldType) {
483497
List<Mapper> updatedMappers = null;

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

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919

2020
package org.elasticsearch.index.mapper;
2121

22-
import java.util.HashSet;
2322
import org.apache.lucene.index.IndexableField;
2423
import org.elasticsearch.Version;
2524
import org.elasticsearch.cluster.metadata.IndexMetadata;
@@ -41,6 +40,7 @@
4140
import java.io.UncheckedIOException;
4241
import java.util.Collection;
4342
import java.util.Collections;
43+
import java.util.HashSet;
4444
import java.util.function.Function;
4545

4646
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
@@ -749,4 +749,31 @@ public void testReorderParentBWC() throws IOException {
749749
}
750750
}
751751
}
752+
753+
public void testMergeNestedMappings() throws IOException {
754+
MapperService mapperService = createIndex("index1", Settings.EMPTY, MapperService.SINGLE_MAPPING_NAME, jsonBuilder().startObject()
755+
.startObject("properties")
756+
.startObject("nested1")
757+
.field("type", "nested")
758+
.endObject()
759+
.endObject().endObject()).mapperService();
760+
761+
String mapping1 = Strings.toString(XContentFactory.jsonBuilder().startObject().startObject("type").startObject("properties")
762+
.startObject("nested1").field("type", "nested").field("include_in_parent", true)
763+
.endObject().endObject().endObject().endObject());
764+
765+
// cannot update `include_in_parent` dynamically
766+
MapperException e1 = expectThrows(MapperException.class, () -> mapperService.merge("type",
767+
new CompressedXContent(mapping1), MergeReason.MAPPING_UPDATE));
768+
assertEquals("The [include_in_parent] parameter can't be updated for the nested object mapping [nested1].", e1.getMessage());
769+
770+
String mapping2 = Strings.toString(XContentFactory.jsonBuilder().startObject().startObject("type").startObject("properties")
771+
.startObject("nested1").field("type", "nested").field("include_in_root", true)
772+
.endObject().endObject().endObject().endObject());
773+
774+
// cannot update `include_in_root` dynamically
775+
MapperException e2 = expectThrows(MapperException.class, () -> mapperService.merge("type",
776+
new CompressedXContent(mapping2), MergeReason.MAPPING_UPDATE));
777+
assertEquals("The [include_in_root] parameter can't be updated for the nested object mapping [nested1].", e2.getMessage());
778+
}
752779
}

0 commit comments

Comments
 (0)