keep _parent field while updating child type mapping (#24407)

parent/child: Allow updating mapping without specifying `_parent` field on each update.

Prior to this change when a mapping has a `_parent` field then any update (also updates that didn't modify the `_parent` field) to the mapping involved specifying the `_parent` field again. With this change specifying the `_parent` field on each mapping update is no longer required.

Closes #23381
This commit is contained in:
Yu 2017-06-07 10:51:21 +02:00 committed by Martijn van Groningen
parent 2f5f27fafa
commit 14913fdc37
2 changed files with 71 additions and 9 deletions

View File

@ -296,9 +296,10 @@ public class ParentFieldMapper extends MetadataFieldMapper {
@Override
protected void doMerge(Mapper mergeWith, boolean updateAllTypes) {
ParentFieldType currentFieldType = (ParentFieldType) fieldType.clone();
super.doMerge(mergeWith, updateAllTypes);
ParentFieldMapper fieldMergeWith = (ParentFieldMapper) mergeWith;
if (Objects.equals(parentType, fieldMergeWith.parentType) == false) {
if (fieldMergeWith.parentType != null && Objects.equals(parentType, fieldMergeWith.parentType) == false) {
throw new IllegalArgumentException("The _parent field's type option can't be changed: [" + parentType + "]->[" + fieldMergeWith.parentType + "]");
}
@ -309,7 +310,7 @@ public class ParentFieldMapper extends MetadataFieldMapper {
}
if (active()) {
fieldType = fieldMergeWith.fieldType.clone();
fieldType = currentFieldType;
}
}

View File

@ -168,9 +168,9 @@ public class DocumentMapperMergeTests extends ESSingleNodeTestCase {
barrier.await();
for (int i = 0; i < 200 && stopped.get() == false; i++) {
final String fieldName = Integer.toString(i);
ParsedDocument doc = documentMapper.parse(SourceToParse.source("test",
"test",
fieldName,
ParsedDocument doc = documentMapper.parse(SourceToParse.source("test",
"test",
fieldName,
new BytesArray("{ \"" + fieldName + "\" : \"test\" }"),
XContentType.JSON));
Mapping update = doc.dynamicMappingsUpdate();
@ -191,10 +191,10 @@ public class DocumentMapperMergeTests extends ESSingleNodeTestCase {
while(stopped.get() == false) {
final String fieldName = lastIntroducedFieldName.get();
final BytesReference source = new BytesArray("{ \"" + fieldName + "\" : \"test\" }");
ParsedDocument parsedDoc = documentMapper.parse(SourceToParse.source("test",
"test",
"random",
source,
ParsedDocument parsedDoc = documentMapper.parse(SourceToParse.source("test",
"test",
"random",
source,
XContentType.JSON));
if (parsedDoc.dynamicMappingsUpdate() != null) {
// not in the mapping yet, try again
@ -235,4 +235,65 @@ public class DocumentMapperMergeTests extends ESSingleNodeTestCase {
assertNotNull(mapper.mappers().getMapper("foo"));
assertFalse(mapper.sourceMapper().enabled());
}
public void testMergeChildType() throws IOException {
DocumentMapperParser parser = createIndex("test").mapperService().documentMapperParser();
String initMapping = XContentFactory.jsonBuilder().startObject().startObject("child")
.startObject("_parent").field("type", "parent").endObject()
.endObject().endObject().string();
DocumentMapper initMapper = parser.parse("child", new CompressedXContent(initMapping));
assertThat(initMapper.mappers().getMapper("_parent#parent"), notNullValue());
String updatedMapping1 = XContentFactory.jsonBuilder().startObject().startObject("child")
.startObject("properties")
.startObject("name").field("type", "text").endObject()
.endObject().endObject().endObject().string();
DocumentMapper updatedMapper1 = parser.parse("child", new CompressedXContent(updatedMapping1));
DocumentMapper mergedMapper1 = initMapper.merge(updatedMapper1.mapping(), false);
assertThat(mergedMapper1.mappers().getMapper("_parent#parent"), notNullValue());
assertThat(mergedMapper1.mappers().getMapper("name"), notNullValue());
String updatedMapping2 = XContentFactory.jsonBuilder().startObject().startObject("child")
.startObject("_parent").field("type", "parent").endObject()
.startObject("properties")
.startObject("age").field("type", "byte").endObject()
.endObject().endObject().endObject().string();
DocumentMapper updatedMapper2 = parser.parse("child", new CompressedXContent(updatedMapping2));
DocumentMapper mergedMapper2 = mergedMapper1.merge(updatedMapper2.mapping(), false);
assertThat(mergedMapper2.mappers().getMapper("_parent#parent"), notNullValue());
assertThat(mergedMapper2.mappers().getMapper("name"), notNullValue());
assertThat(mergedMapper2.mappers().getMapper("age"), notNullValue());
String modParentMapping = XContentFactory.jsonBuilder().startObject().startObject("child")
.startObject("_parent").field("type", "new_parent").endObject()
.endObject().endObject().string();
DocumentMapper modParentMapper = parser.parse("child", new CompressedXContent(modParentMapping));
Exception e = expectThrows(IllegalArgumentException.class, () -> initMapper.merge(modParentMapper.mapping(), false));
assertThat(e.getMessage(), containsString("The _parent field's type option can't be changed: [parent]->[new_parent]"));
}
public void testMergeAddingParent() throws IOException {
DocumentMapperParser parser = createIndex("test").mapperService().documentMapperParser();
String initMapping = XContentFactory.jsonBuilder().startObject().startObject("cowboy")
.startObject("properties")
.startObject("name").field("type", "text").endObject()
.endObject().endObject().endObject().string();
DocumentMapper initMapper = parser.parse("cowboy", new CompressedXContent(initMapping));
assertThat(initMapper.mappers().getMapper("name"), notNullValue());
String updatedMapping = XContentFactory.jsonBuilder().startObject().startObject("cowboy")
.startObject("_parent").field("type", "parent").endObject()
.startObject("properties")
.startObject("age").field("type", "byte").endObject()
.endObject().endObject().endObject().string();
DocumentMapper updatedMapper = parser.parse("cowboy", new CompressedXContent(updatedMapping));
Exception e = expectThrows(IllegalArgumentException.class, () -> initMapper.merge(updatedMapper.mapping(), false));
assertThat(e.getMessage(), containsString("The _parent field's type option can't be changed: [null]->[parent]"));
}
}