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 <gbl_long@163.com>
This commit is contained in:
parent
b810f0024a
commit
d7cded8d7a
|
@ -41,6 +41,15 @@ Previously, Elasticsearch accepted mapping updates that tried to change the
|
|||
request didn't throw an error. As of 7.8, requests that attempt to change
|
||||
`enabled` on the root mapping will fail.
|
||||
|
||||
[discrete]
|
||||
[[prevent-include-in-root-change]]
|
||||
==== `include_in_root` and `include_in_parent` cannot be changed
|
||||
|
||||
Elasticsearch previously accepted mapping updates that changed the
|
||||
`include_in_root` and `include_in_parent` settings. The update was not
|
||||
applied, but the request didn't throw an error. As of 7.8, requests that
|
||||
attempt to change these settings will fail.
|
||||
|
||||
[discrete]
|
||||
[[breaking_78_settings_changes]]
|
||||
=== Settings changes
|
||||
|
|
|
@ -459,9 +459,7 @@ public class ObjectMapper extends Mapper implements Cloneable {
|
|||
this.dynamic = mergeWith.dynamic;
|
||||
}
|
||||
|
||||
if (isEnabled() != mergeWith.isEnabled()) {
|
||||
throw new MapperException("The [enabled] parameter can't be updated for the object mapping [" + name() + "].");
|
||||
}
|
||||
checkObjectMapperParameters(mergeWith);
|
||||
|
||||
for (Mapper mergeWithMapper : mergeWith) {
|
||||
Mapper mergeIntoMapper = mappers.get(mergeWithMapper.simpleName());
|
||||
|
@ -478,6 +476,22 @@ public class ObjectMapper extends Mapper implements Cloneable {
|
|||
}
|
||||
}
|
||||
|
||||
private void checkObjectMapperParameters(final ObjectMapper mergeWith) {
|
||||
if (isEnabled() != mergeWith.isEnabled()) {
|
||||
throw new MapperException("The [enabled] parameter can't be updated for the object mapping [" + name() + "].");
|
||||
}
|
||||
|
||||
if (nested().isIncludeInParent() != mergeWith.nested().isIncludeInParent()) {
|
||||
throw new MapperException("The [include_in_parent] parameter can't be updated for the nested object mapping [" +
|
||||
name() + "].");
|
||||
}
|
||||
|
||||
if (nested().isIncludeInRoot() != mergeWith.nested().isIncludeInRoot()) {
|
||||
throw new MapperException("The [include_in_root] parameter can't be updated for the nested object mapping [" +
|
||||
name() + "].");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectMapper updateFieldType(Map<String, MappedFieldType> fullNameToFieldType) {
|
||||
List<Mapper> updatedMappers = null;
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
|
||||
package org.elasticsearch.index.mapper;
|
||||
|
||||
import java.util.HashSet;
|
||||
import org.apache.lucene.index.IndexableField;
|
||||
import org.elasticsearch.Version;
|
||||
import org.elasticsearch.cluster.metadata.IndexMetadata;
|
||||
|
@ -41,6 +40,7 @@ import java.io.IOException;
|
|||
import java.io.UncheckedIOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.function.Function;
|
||||
|
||||
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
|
||||
|
@ -749,4 +749,31 @@ public class NestedObjectMapperTests extends ESSingleNodeTestCase {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void testMergeNestedMappings() throws IOException {
|
||||
MapperService mapperService = createIndex("index1", Settings.EMPTY, MapperService.SINGLE_MAPPING_NAME, jsonBuilder().startObject()
|
||||
.startObject("properties")
|
||||
.startObject("nested1")
|
||||
.field("type", "nested")
|
||||
.endObject()
|
||||
.endObject().endObject()).mapperService();
|
||||
|
||||
String mapping1 = Strings.toString(XContentFactory.jsonBuilder().startObject().startObject("type").startObject("properties")
|
||||
.startObject("nested1").field("type", "nested").field("include_in_parent", true)
|
||||
.endObject().endObject().endObject().endObject());
|
||||
|
||||
// cannot update `include_in_parent` dynamically
|
||||
MapperException e1 = expectThrows(MapperException.class, () -> mapperService.merge("type",
|
||||
new CompressedXContent(mapping1), MergeReason.MAPPING_UPDATE));
|
||||
assertEquals("The [include_in_parent] parameter can't be updated for the nested object mapping [nested1].", e1.getMessage());
|
||||
|
||||
String mapping2 = Strings.toString(XContentFactory.jsonBuilder().startObject().startObject("type").startObject("properties")
|
||||
.startObject("nested1").field("type", "nested").field("include_in_root", true)
|
||||
.endObject().endObject().endObject().endObject());
|
||||
|
||||
// cannot update `include_in_root` dynamically
|
||||
MapperException e2 = expectThrows(MapperException.class, () -> mapperService.merge("type",
|
||||
new CompressedXContent(mapping2), MergeReason.MAPPING_UPDATE));
|
||||
assertEquals("The [include_in_root] parameter can't be updated for the nested object mapping [nested1].", e2.getMessage());
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue