Fail to index fields with dots in field names when one of the intermediate objects is nested. (#21787)

Closes #21726
This commit is contained in:
Adrien Grand 2016-11-28 09:57:32 +01:00 committed by GitHub
parent 6f95261632
commit 243a788289
2 changed files with 52 additions and 1 deletions

View File

@ -859,7 +859,8 @@ final class DocumentParser {
Mapper.BuilderContext builderContext = new Mapper.BuilderContext(context.indexSettings(), context.path());
mapper = (ObjectMapper) builder.build(builderContext);
if (mapper.nested() != ObjectMapper.Nested.NO) {
throw new MapperParsingException("It is forbidden to create dynamic nested objects ([" + context.path().pathAsText(paths[i]) + "]) through `copy_to`");
throw new MapperParsingException("It is forbidden to create dynamic nested objects ([" + context.path().pathAsText(paths[i])
+ "]) through `copy_to` or dots in field names");
}
context.addDynamicMapper(mapper);
break;
@ -909,6 +910,11 @@ final class DocumentParser {
return null;
}
objectMapper = (ObjectMapper)mapper;
if (objectMapper.nested().isNested()) {
throw new MapperParsingException("Cannot add a value for field ["
+ fieldName + "] since one of the intermediate objects is mapped as a nested object: ["
+ mapper.name() + "]");
}
}
return objectMapper.getMapper(subfields[subfields.length - 1]);
}

View File

@ -120,6 +120,51 @@ public class DocumentParserTests extends ESSingleNodeTestCase {
assertEquals("789", values[2]);
}
public void testDotsWithExistingNestedMapper() throws Exception {
DocumentMapperParser mapperParser = createIndex("test").mapperService().documentMapperParser();
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type").startObject("properties")
.startObject("foo").field("type", "nested").startObject("properties")
.startObject("bar").field("type", "integer")
.endObject().endObject().endObject().endObject().endObject().endObject().string();
DocumentMapper mapper = mapperParser.parse("type", new CompressedXContent(mapping));
BytesReference bytes = XContentFactory.jsonBuilder()
.startObject()
.field("foo.bar", 123)
.endObject().bytes();
MapperParsingException e = expectThrows(MapperParsingException.class,
() -> mapper.parse("test", "type", "1", bytes));
assertEquals(
"Cannot add a value for field [foo.bar] since one of the intermediate objects is mapped as a nested object: [foo]",
e.getMessage());
}
public void testDotsWithDynamicNestedMapper() throws Exception {
DocumentMapperParser mapperParser = createIndex("test").mapperService().documentMapperParser();
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
.startArray("dynamic_templates")
.startObject()
.startObject("objects_as_nested")
.field("match_mapping_type", "object")
.startObject("mapping")
.field("type", "nested")
.endObject()
.endObject()
.endObject()
.endArray().endObject().endObject().string();
DocumentMapper mapper = mapperParser.parse("type", new CompressedXContent(mapping));
BytesReference bytes = XContentFactory.jsonBuilder()
.startObject()
.field("foo.bar",42)
.endObject().bytes();
MapperParsingException e = expectThrows(MapperParsingException.class,
() -> mapper.parse("test", "type", "1", bytes));
assertEquals(
"It is forbidden to create dynamic nested objects ([foo]) through `copy_to` or dots in field names",
e.getMessage());
}
public void testPropagateDynamicWithExistingMapper() throws Exception {
DocumentMapperParser mapperParser = createIndex("test").mapperService().documentMapperParser();
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")