/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.index.mapper;
import org.elasticsearch.Version;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.common.bytes.BytesArray;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.compress.CompressedXContent;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.IndexService;
import org.elasticsearch.index.mapper.ParseContext.Document;
import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.test.ESSingleNodeTestCase;
import org.elasticsearch.test.InternalSettingsPlugin;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.test.StreamsUtils.copyToBytesFromClasspath;
import static org.elasticsearch.test.StreamsUtils.copyToStringFromClasspath;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.not;
// TODO: make this a real unit test
public class DocumentParserTests extends ESSingleNodeTestCase {
@Override
protected Collection<Class<? extends Plugin>> getPlugins() {
return pluginList(InternalSettingsPlugin.class);
}
public void testFieldDisabled() throws Exception {
DocumentMapperParser mapperParser = createIndex("test").mapperService().documentMapperParser();
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type").startObject("properties")
.startObject("foo").field("enabled", false).endObject()
.startObject("bar").field("type", "integer").endObject()
.endObject().endObject().endObject().string();
DocumentMapper mapper = mapperParser.parse("type", new CompressedXContent(mapping));
BytesReference bytes = XContentFactory.jsonBuilder()
.startObject()
.field("foo", "1234")
.field("bar", 10)
.endObject().bytes();
ParsedDocument doc = mapper.parse(SourceToParse.source("test", "type", "1", bytes, XContentType.JSON));
assertNull(doc.rootDoc().getField("foo"));
assertNotNull(doc.rootDoc().getField("bar"));
assertNotNull(doc.rootDoc().getField(IdFieldMapper.NAME));
}
public void testDotsWithExistingMapper() throws Exception {
DocumentMapperParser mapperParser = createIndex("test").mapperService().documentMapperParser();
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type").startObject("properties")
.startObject("foo").startObject("properties")
.startObject("bar").startObject("properties")
.startObject("baz").field("type", "integer")
.endObject().endObject().endObject().endObject().endObject().endObject().endObject().endObject().string();
DocumentMapper mapper = mapperParser.parse("type", new CompressedXContent(mapping));
BytesReference bytes = XContentFactory.jsonBuilder()
.startObject()
.field("foo.bar.baz", 123)
.startObject("foo")
.field("bar.baz", 456)
.endObject()
.startObject("foo.bar")
.field("baz", 789)
.endObject()
.endObject().bytes();
ParsedDocument doc = mapper.parse(SourceToParse.source("test", "type", "1", bytes, XContentType.JSON));
assertNull(doc.dynamicMappingsUpdate()); // no update!
String[] values = doc.rootDoc().getValues("foo.bar.baz");
assertEquals(3, values.length);
assertEquals("123", values[0]);
assertEquals("456", values[1]);
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(SourceToParse.source("test", "type", "1", bytes, XContentType.JSON)));
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(SourceToParse.source("test", "type", "1", bytes, XContentType.JSON)));
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")
.field("dynamic", false)
.startObject("properties")
.startObject("foo")
.field("type", "object")
.field("dynamic", true)
.startObject("properties")
.endObject().endObject().endObject().endObject().endObject().string();
DocumentMapper mapper = mapperParser.parse("type", new CompressedXContent(mapping));
BytesReference bytes = XContentFactory.jsonBuilder()
.startObject().startObject("foo")
.field("bar", "something")
.endObject().endObject().bytes();
ParsedDocument doc = mapper.parse(SourceToParse.source("test", "type", "1", bytes, XContentType.JSON));
assertNotNull(doc.dynamicMappingsUpdate());
assertNotNull(doc.rootDoc().getField("foo.bar"));
}
public void testPropagateDynamicWithDynamicMapper() throws Exception {
DocumentMapperParser mapperParser = createIndex("test").mapperService().documentMapperParser();
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
.field("dynamic", false)
.startObject("properties")
.startObject("foo")
.field("type", "object")
.field("dynamic", true)
.startObject("properties")
.endObject().endObject().endObject().endObject().endObject().string();
DocumentMapper mapper = mapperParser.parse("type", new CompressedXContent(mapping));
BytesReference bytes = XContentFactory.jsonBuilder()
.startObject().startObject("foo").startObject("bar")
.field("baz", "something")
.endObject().endObject().endObject().bytes();
ParsedDocument doc = mapper.parse(SourceToParse.source("test", "type", "1", bytes, XContentType.JSON));
assertNotNull(doc.dynamicMappingsUpdate());
assertNotNull(doc.rootDoc().getField("foo.bar.baz"));
}
public void testDynamicRootFallback() throws Exception {
DocumentMapperParser mapperParser = createIndex("test").mapperService().documentMapperParser();
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
.field("dynamic", false)
.startObject("properties")
.startObject("foo")
.field("type", "object")
.startObject("properties")
.endObject().endObject().endObject().endObject().endObject().string();
DocumentMapper mapper = mapperParser.parse("type", new CompressedXContent(mapping));
BytesReference bytes = XContentFactory.jsonBuilder()
.startObject().startObject("foo")
.field("bar", "something")
.endObject().endObject().bytes();
ParsedDocument doc = mapper.parse(SourceToParse.source("test", "type", "1", bytes, XContentType.JSON));
assertNull(doc.dynamicMappingsUpdate());
assertNull(doc.rootDoc().getField("foo.bar"));
}
DocumentMapper createDummyMapping(MapperService mapperService) throws Exception {
String mapping = jsonBuilder().startObject().startObject("type").startObject("properties")
.startObject("y").field("type", "object").endObject()
.startObject("x").startObject("properties")
.startObject("subx").field("type", "object").startObject("properties")
.startObject("subsubx").field("type", "object")
.endObject().endObject().endObject().endObject().endObject().endObject().endObject().endObject().string();
DocumentMapper defaultMapper = mapperService.documentMapperParser().parse("type", new CompressedXContent(mapping));
return defaultMapper;
}
// creates an object mapper, which is about 100x harder than it should be....
ObjectMapper createObjectMapper(MapperService mapperService, String name) throws Exception {
ParseContext context = new ParseContext.InternalParseContext(
Settings.builder().put(IndexMetaData.SETTING_VERSION_CREATED, Version.CURRENT).build(),
mapperService.documentMapperParser(), mapperService.documentMapper("type"), null, null);
String[] nameParts = name.split("\\.");
for (int i = 0; i < nameParts.length - 1; ++i) {
context.path().add(nameParts[i]);
}
Mapper.Builder builder = new ObjectMapper.Builder(nameParts[nameParts.length - 1]).enabled(true);
Mapper.BuilderContext builderContext = new Mapper.BuilderContext(context.indexSettings(), context.path());
return (ObjectMapper)builder.build(builderContext);
}
public void testEmptyMappingUpdate() throws Exception {
DocumentMapper docMapper = createDummyMapping(createIndex("test").mapperService());
assertNull(DocumentParser.createDynamicUpdate(docMapper.mapping(), docMapper, Collections.emptyList()));
}
public void testSingleMappingUpdate() throws Exception {
DocumentMapper docMapper = createDummyMapping(createIndex("test").mapperService());
List<Mapper> updates = Collections.singletonList(new MockFieldMapper("foo"));
Mapping mapping = DocumentParser.createDynamicUpdate(docMapper.mapping(), docMapper, updates);
assertNotNull(mapping.root().getMapper("foo"));
}
public void testSubfieldMappingUpdate() throws Exception {
DocumentMapper docMapper = createDummyMapping(createIndex("test").mapperService());
List<Mapper> updates = Collections.singletonList(new MockFieldMapper("x.foo"));
Mapping mapping = DocumentParser.createDynamicUpdate(docMapper.mapping(), docMapper, updates);
Mapper xMapper = mapping.root().getMapper("x");
assertNotNull(xMapper);
assertTrue(xMapper instanceof ObjectMapper);
assertNotNull(((ObjectMapper)xMapper).getMapper("foo"));
assertNull(((ObjectMapper)xMapper).getMapper("subx"));
}
public void testMultipleSubfieldMappingUpdate() throws Exception {
DocumentMapper docMapper = createDummyMapping(createIndex("test").mapperService());
List<Mapper> updates = new ArrayList<>();
updates.add(new MockFieldMapper("x.foo"));
updates.add(new MockFieldMapper("x.bar"));
Mapping mapping = DocumentParser.createDynamicUpdate(docMapper.mapping(), docMapper, updates);
Mapper xMapper = mapping.root().getMapper("x");
assertNotNull(xMapper);
assertTrue(xMapper instanceof ObjectMapper);
assertNotNull(((ObjectMapper)xMapper).getMapper("foo"));
assertNotNull(((ObjectMapper)xMapper).getMapper("bar"));
assertNull(((ObjectMapper)xMapper).getMapper("subx"));
}
public void testDeepSubfieldMappingUpdate() throws Exception {
DocumentMapper docMapper = createDummyMapping(createIndex("test").mapperService());
List<Mapper> updates = Collections.singletonList(new MockFieldMapper("x.subx.foo"));
Mapping mapping = DocumentParser.createDynamicUpdate(docMapper.mapping(), docMapper, updates);
Mapper xMapper = mapping.root().getMapper("x");
assertNotNull(xMapper);
assertTrue(xMapper instanceof ObjectMapper);
Mapper subxMapper = ((ObjectMapper)xMapper).getMapper("subx");
assertTrue(subxMapper instanceof ObjectMapper);
assertNotNull(((ObjectMapper)subxMapper).getMapper("foo"));
assertNull(((ObjectMapper)subxMapper).getMapper("subsubx"));
}
public void testDeepSubfieldAfterSubfieldMappingUpdate() throws Exception {
DocumentMapper docMapper = createDummyMapping(createIndex("test").mapperService());
List<Mapper> updates = new ArrayList<>();
updates.add(new MockFieldMapper("x.a"));
updates.add(new MockFieldMapper("x.subx.b"));
Mapping mapping = DocumentParser.createDynamicUpdate(docMapper.mapping(), docMapper, updates);
Mapper xMapper = mapping.root().getMapper("x");
assertNotNull(xMapper);
assertTrue(xMapper instanceof ObjectMapper);
assertNotNull(((ObjectMapper)xMapper).getMapper("a"));
Mapper subxMapper = ((ObjectMapper)xMapper).getMapper("subx");
assertTrue(subxMapper instanceof ObjectMapper);
assertNotNull(((ObjectMapper)subxMapper).getMapper("b"));
}
public void testObjectMappingUpdate() throws Exception {
MapperService mapperService = createIndex("test").mapperService();
DocumentMapper docMapper = createDummyMapping(mapperService);
List<Mapper> updates = new ArrayList<>();
updates.add(createObjectMapper(mapperService, "foo"));
updates.add(createObjectMapper(mapperService, "foo.bar"));
updates.add(new MockFieldMapper("foo.bar.baz"));
updates.add(new MockFieldMapper("foo.field"));
Mapping mapping = DocumentParser.createDynamicUpdate(docMapper.mapping(), docMapper, updates);
Mapper fooMapper = mapping.root().getMapper("foo");
assertNotNull(fooMapper);
assertTrue(fooMapper instanceof ObjectMapper);
assertNotNull(((ObjectMapper)fooMapper).getMapper("field"));
Mapper barMapper = ((ObjectMapper)fooMapper).getMapper("bar");
assertTrue(barMapper instanceof ObjectMapper);
assertNotNull(((ObjectMapper)barMapper).getMapper("baz"));
}
public void testDynamicGeoPointArrayWithTemplate() throws Exception {
DocumentMapperParser mapperParser = createIndex("test").mapperService().documentMapperParser();
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
.startArray("dynamic_templates").startObject().startObject("georule")
.field("match", "foo*")
.startObject("mapping").field("type", "geo_point").field("doc_values", false).endObject()
.endObject().endObject().endArray().endObject().endObject().string();
DocumentMapper mapper = mapperParser.parse("type", new CompressedXContent(mapping));
BytesReference bytes = XContentFactory.jsonBuilder()
.startObject().startArray("foo")
.startArray().value(0).value(0).endArray()
.startArray().value(1).value(1).endArray()
.endArray().endObject().bytes();
ParsedDocument doc = mapper.parse(SourceToParse.source("test", "type", "1", bytes, XContentType.JSON));
assertEquals(2, doc.rootDoc().getFields("foo").length);
}
public void testDynamicLongArrayWithTemplate() throws Exception {
DocumentMapperParser mapperParser = createIndex("test").mapperService().documentMapperParser();
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
.startArray("dynamic_templates").startObject().startObject("georule")
.field("match", "foo*")
.startObject("mapping").field("type", "long").endObject()
.endObject().endObject().endArray().endObject().endObject().string();
DocumentMapper mapper = mapperParser.parse("type", new CompressedXContent(mapping));
BytesReference bytes = XContentFactory.jsonBuilder()
.startObject().startArray("foo")
.value(0)
.value(1)
.endArray().endObject().bytes();
ParsedDocument doc = mapper.parse(SourceToParse.source("test", "type", "1", bytes, XContentType.JSON));
assertEquals(4, doc.rootDoc().getFields("foo").length);
}
public void testDynamicLongArray() throws Exception {
DocumentMapperParser mapperParser = createIndex("test").mapperService().documentMapperParser();
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
.endObject().endObject().string();
DocumentMapper mapper = mapperParser.parse("type", new CompressedXContent(mapping));
BytesReference bytes = XContentFactory.jsonBuilder()
.startObject().startArray("foo")
.value(0)
.value(1)
.endArray().endObject().bytes();
ParsedDocument doc = mapper.parse(SourceToParse.source("test", "type", "1", bytes, XContentType.JSON));
assertEquals(4, doc.rootDoc().getFields("foo").length);
}
public void testDynamicFalseLongArray() throws Exception {
DocumentMapperParser mapperParser = createIndex("test").mapperService().documentMapperParser();
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type").field("dynamic", "false")
.endObject().endObject().string();
DocumentMapper mapper = mapperParser.parse("type", new CompressedXContent(mapping));
BytesReference bytes = XContentFactory.jsonBuilder()
.startObject().startArray("foo")
.value(0)
.value(1)
.endArray().endObject().bytes();
ParsedDocument doc = mapper.parse(SourceToParse.source("test", "type", "1", bytes, XContentType.JSON));
assertEquals(0, doc.rootDoc().getFields("foo").length);
}
public void testDynamicStrictLongArray() throws Exception {
DocumentMapperParser mapperParser = createIndex("test").mapperService().documentMapperParser();
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type").field("dynamic", "strict")
.endObject().endObject().string();
DocumentMapper mapper = mapperParser.parse("type", new CompressedXContent(mapping));
BytesReference bytes = XContentFactory.jsonBuilder()
.startObject().startArray("foo")
.value(0)
.value(1)
.endArray().endObject().bytes();
StrictDynamicMappingException exception = expectThrows(StrictDynamicMappingException.class,
() -> mapper.parse(SourceToParse.source("test", "type", "1", bytes, XContentType.JSON)));
assertEquals("mapping set to strict, dynamic introduction of [foo] within [type] is not allowed", exception.getMessage());
}
public void testMappedGeoPointArray() throws Exception {
DocumentMapperParser mapperParser = createIndex("test").mapperService().documentMapperParser();
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
.startObject("properties").startObject("foo").field("type", "geo_point").field("doc_values", false)
.endObject().endObject().endObject().endObject().string();
DocumentMapper mapper = mapperParser.parse("type", new CompressedXContent(mapping));
BytesReference bytes = XContentFactory.jsonBuilder()
.startObject().startArray("foo")
.startArray().value(0).value(0).endArray()
.startArray().value(1).value(1).endArray()
.endArray().endObject().bytes();
ParsedDocument doc = mapper.parse(SourceToParse.source("test", "type", "1", bytes, XContentType.JSON));
assertEquals(2, doc.rootDoc().getFields("foo").length);
}
public void testMappedLongArray() throws Exception {
DocumentMapperParser mapperParser = createIndex("test").mapperService().documentMapperParser();
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
.startObject("properties").startObject("foo").field("type", "long")
.endObject().endObject().endObject().endObject().string();
DocumentMapper mapper = mapperParser.parse("type", new CompressedXContent(mapping));
BytesReference bytes = XContentFactory.jsonBuilder()
.startObject().startArray("foo")
.value(0)
.value(1)
.endArray().endObject().bytes();
ParsedDocument doc = mapper.parse(SourceToParse.source("test", "type", "1", bytes, XContentType.JSON));
assertEquals(4, doc.rootDoc().getFields("foo").length);
}
public void testDynamicObjectWithTemplate() throws Exception {
DocumentMapperParser mapperParser = createIndex("test").mapperService().documentMapperParser();
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
.startArray("dynamic_templates").startObject().startObject("georule")
.field("match", "foo*")
.startObject("mapping").field("type", "object")
.startObject("properties").startObject("bar").field("type", "keyword").endObject().endObject().endObject()
.endObject().endObject().endArray().endObject().endObject().string();
DocumentMapper mapper = mapperParser.parse("type", new CompressedXContent(mapping));
BytesReference bytes = XContentFactory.jsonBuilder()
.startObject().startObject("foo")
.field("bar", "baz")
.endObject().endObject().bytes();
ParsedDocument doc = mapper.parse(SourceToParse.source("test", "type", "1", bytes, XContentType.JSON));
assertEquals(2, doc.rootDoc().getFields("foo.bar").length);
}
public void testDynamicFalseObject() throws Exception {
DocumentMapperParser mapperParser = createIndex("test").mapperService().documentMapperParser();
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type").field("dynamic", "false")
.endObject().endObject().string();
DocumentMapper mapper = mapperParser.parse("type", new CompressedXContent(mapping));
BytesReference bytes = XContentFactory.jsonBuilder()
.startObject().startObject("foo")
.field("bar", "baz")
.endObject().endObject().bytes();
ParsedDocument doc = mapper.parse(SourceToParse.source("test", "type", "1", bytes, XContentType.JSON));
assertEquals(0, doc.rootDoc().getFields("foo.bar").length);
}
public void testDynamicStrictObject() throws Exception {
DocumentMapperParser mapperParser = createIndex("test").mapperService().documentMapperParser();
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type").field("dynamic", "strict")
.endObject().endObject().string();
DocumentMapper mapper = mapperParser.parse("type", new CompressedXContent(mapping));
BytesReference bytes = XContentFactory.jsonBuilder()
.startObject().startObject("foo")
.field("bar", "baz")
.endObject().endObject().bytes();
StrictDynamicMappingException exception = expectThrows(StrictDynamicMappingException.class,
() -> mapper.parse(SourceToParse.source("test", "type", "1", bytes, XContentType.JSON)));
assertEquals("mapping set to strict, dynamic introduction of [foo] within [type] is not allowed", exception.getMessage());
}
public void testDynamicFalseValue() throws Exception {
DocumentMapperParser mapperParser = createIndex("test").mapperService().documentMapperParser();
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type").field("dynamic", "false")
.endObject().endObject().string();
DocumentMapper mapper = mapperParser.parse("type", new CompressedXContent(mapping));
BytesReference bytes = XContentFactory.jsonBuilder()
.startObject()
.field("bar", "baz")
.endObject().bytes();
ParsedDocument doc = mapper.parse(SourceToParse.source("test", "type", "1", bytes, XContentType.JSON));
assertEquals(0, doc.rootDoc().getFields("bar").length);
}
public void testDynamicStrictValue() throws Exception {
DocumentMapperParser mapperParser = createIndex("test").mapperService().documentMapperParser();
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type").field("dynamic", "strict")
.endObject().endObject().string();
DocumentMapper mapper = mapperParser.parse("type", new CompressedXContent(mapping));
BytesReference bytes = XContentFactory.jsonBuilder()
.startObject()
.field("bar", "baz")
.endObject().bytes();
StrictDynamicMappingException exception = expectThrows(StrictDynamicMappingException.class,
() -> mapper.parse(SourceToParse.source("test", "type", "1", bytes, XContentType.JSON)));
assertEquals("mapping set to strict, dynamic introduction of [bar] within [type] is not allowed", exception.getMessage());
}
public void testDynamicFalseNull() throws Exception {
DocumentMapperParser mapperParser = createIndex("test").mapperService().documentMapperParser();
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type").field("dynamic", "false")
.endObject().endObject().string();
DocumentMapper mapper = mapperParser.parse("type", new CompressedXContent(mapping));
BytesReference bytes = XContentFactory.jsonBuilder()
.startObject()
.field("bar", (String) null)
.endObject().bytes();
ParsedDocument doc = mapper.parse(SourceToParse.source("test", "type", "1", bytes, XContentType.JSON));
assertEquals(0, doc.rootDoc().getFields("bar").length);
}
public void testDynamicStrictNull() throws Exception {
DocumentMapperParser mapperParser = createIndex("test").mapperService().documentMapperParser();
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type").field("dynamic", "strict")
.endObject().endObject().string();
DocumentMapper mapper = mapperParser.parse("type", new CompressedXContent(mapping));
BytesReference bytes = XContentFactory.jsonBuilder()
.startObject()
.field("bar", (String) null)
.endObject().bytes();
StrictDynamicMappingException exception = expectThrows(StrictDynamicMappingException.class,
() -> mapper.parse(SourceToParse.source("test", "type", "1", bytes, XContentType.JSON)));
assertEquals("mapping set to strict, dynamic introduction of [bar] within [type] is not allowed", exception.getMessage());
}
public void testMappedNullValue() throws Exception {
DocumentMapperParser mapperParser = createIndex("test").mapperService().documentMapperParser();
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
.startObject("properties").startObject("foo").field("type", "long")
.endObject().endObject().endObject().endObject().string();
DocumentMapper mapper = mapperParser.parse("type", new CompressedXContent(mapping));
BytesReference bytes = XContentFactory.jsonBuilder()
.startObject().field("foo", (Long) null)
.endObject().bytes();
ParsedDocument doc = mapper.parse(SourceToParse.source("test", "type", "1", bytes, XContentType.JSON));
assertEquals(0, doc.rootDoc().getFields("foo").length);
}
public void testDynamicDottedFieldNameLongArray() throws Exception {
DocumentMapperParser mapperParser = createIndex("test").mapperService().documentMapperParser();
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
.endObject().endObject().string();
DocumentMapper mapper = mapperParser.parse("type", new CompressedXContent(mapping));
BytesReference bytes = XContentFactory.jsonBuilder()
.startObject().startArray("foo.bar.baz")
.value(0)
.value(1)
.endArray().endObject().bytes();
ParsedDocument doc = mapper.parse(SourceToParse.source("test", "type", "1", bytes, XContentType.JSON));
assertEquals(4, doc.rootDoc().getFields("foo.bar.baz").length);
Mapper fooMapper = doc.dynamicMappingsUpdate().root().getMapper("foo");
assertNotNull(fooMapper);
assertThat(fooMapper, instanceOf(ObjectMapper.class));
Mapper barMapper = ((ObjectMapper) fooMapper).getMapper("bar");
assertNotNull(barMapper);
assertThat(barMapper, instanceOf(ObjectMapper.class));
Mapper bazMapper = ((ObjectMapper) barMapper).getMapper("baz");
assertNotNull(bazMapper);
assertThat(bazMapper, instanceOf(NumberFieldMapper.class));
}
public void testDynamicDottedFieldNameLongArrayWithParentTemplate() throws Exception {
DocumentMapperParser mapperParser = createIndex("test").mapperService().documentMapperParser();
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
.startArray("dynamic_templates").startObject().startObject("georule")
.field("match", "foo*")
.startObject("mapping").field("type", "object").endObject()
.endObject().endObject().endArray().endObject().endObject().string();
DocumentMapper mapper = mapperParser.parse("type", new CompressedXContent(mapping));
BytesReference bytes = XContentFactory.jsonBuilder()
.startObject().startArray("foo.bar.baz")
.value(0)
.value(1)
.endArray().endObject().bytes();
ParsedDocument doc = mapper.parse(SourceToParse.source("test", "type", "1", bytes, XContentType.JSON));
assertEquals(4, doc.rootDoc().getFields("foo.bar.baz").length);
Mapper fooMapper = doc.dynamicMappingsUpdate().root().getMapper("foo");
assertNotNull(fooMapper);
assertThat(fooMapper, instanceOf(ObjectMapper.class));
Mapper barMapper = ((ObjectMapper) fooMapper).getMapper("bar");
assertNotNull(barMapper);
assertThat(barMapper, instanceOf(ObjectMapper.class));
Mapper bazMapper = ((ObjectMapper) barMapper).getMapper("baz");
assertNotNull(bazMapper);
assertThat(bazMapper, instanceOf(NumberFieldMapper.class));
}
public void testDynamicDottedFieldNameLongArrayWithExistingParent() throws Exception {
DocumentMapperParser mapperParser = createIndex("test").mapperService().documentMapperParser();
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
.startObject("properties") .startObject("foo")
.field("type", "object")
.endObject().endObject().endObject().endObject().string();
DocumentMapper mapper = mapperParser.parse("type", new CompressedXContent(mapping));
BytesReference bytes = XContentFactory.jsonBuilder()
.startObject().startArray("foo.bar.baz")
.value(0)
.value(1)
.endArray().endObject().bytes();
ParsedDocument doc = mapper.parse(SourceToParse.source("test", "type", "1", bytes, XContentType.JSON));
assertEquals(4, doc.rootDoc().getFields("foo.bar.baz").length);
Mapper fooMapper = doc.dynamicMappingsUpdate().root().getMapper("foo");
assertNotNull(fooMapper);
assertThat(fooMapper, instanceOf(ObjectMapper.class));
Mapper barMapper = ((ObjectMapper) fooMapper).getMapper("bar");
assertNotNull(barMapper);
assertThat(barMapper, instanceOf(ObjectMapper.class));
Mapper bazMapper = ((ObjectMapper) barMapper).getMapper("baz");
assertNotNull(bazMapper);
assertThat(bazMapper, instanceOf(NumberFieldMapper.class));
}
public void testDynamicDottedFieldNameLongArrayWithExistingParentWrongType() throws Exception {
DocumentMapperParser mapperParser = createIndex("test").mapperService().documentMapperParser();
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
.startObject("properties") .startObject("foo")
.field("type", "long")
.endObject().endObject().endObject().endObject().string();
DocumentMapper mapper = mapperParser.parse("type", new CompressedXContent(mapping));
BytesReference bytes = XContentFactory.jsonBuilder()
.startObject().startArray("foo.bar.baz")
.value(0)
.value(1)
.endArray().endObject().bytes();
MapperParsingException exception = expectThrows(MapperParsingException.class,
() -> mapper.parse(SourceToParse.source("test", "type", "1", bytes, XContentType.JSON)));
assertEquals("Could not dynamically add mapping for field [foo.bar.baz]. "
+ "Existing mapping for [foo] must be of type object but found [long].", exception.getMessage());
}
public void testDynamicFalseDottedFieldNameLongArray() throws Exception {
DocumentMapperParser mapperParser = createIndex("test").mapperService().documentMapperParser();
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type").field("dynamic", "false")
.endObject().endObject().string();
DocumentMapper mapper = mapperParser.parse("type", new CompressedXContent(mapping));
BytesReference bytes = XContentFactory.jsonBuilder()
.startObject().startArray("foo.bar.baz")
.value(0)
.value(1)
.endArray().endObject().bytes();
ParsedDocument doc = mapper.parse(SourceToParse.source("test", "type", "1", bytes, XContentType.JSON));
assertEquals(0, doc.rootDoc().getFields("foo.bar.baz").length);
}
public void testDynamicStrictDottedFieldNameLongArray() throws Exception {
DocumentMapperParser mapperParser = createIndex("test").mapperService().documentMapperParser();
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type").field("dynamic", "strict")
.endObject().endObject().string();
DocumentMapper mapper = mapperParser.parse("type", new CompressedXContent(mapping));
BytesReference bytes = XContentFactory.jsonBuilder()
.startObject().startArray("foo.bar.baz")
.value(0)
.value(1)
.endArray().endObject().bytes();
StrictDynamicMappingException exception = expectThrows(StrictDynamicMappingException.class,
() -> mapper.parse(SourceToParse.source("test", "type", "1", bytes, XContentType.JSON)));
assertEquals("mapping set to strict, dynamic introduction of [foo] within [type] is not allowed", exception.getMessage());
}
public void testDynamicDottedFieldNameLong() throws Exception {
DocumentMapperParser mapperParser = createIndex("test").mapperService().documentMapperParser();
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
.endObject().endObject().string();
DocumentMapper mapper = mapperParser.parse("type", new CompressedXContent(mapping));
BytesReference bytes = XContentFactory.jsonBuilder()
.startObject().field("foo.bar.baz", 0)
.endObject().bytes();
ParsedDocument doc = mapper.parse(SourceToParse.source("test", "type", "1", bytes, XContentType.JSON));
assertEquals(2, doc.rootDoc().getFields("foo.bar.baz").length);
Mapper fooMapper = doc.dynamicMappingsUpdate().root().getMapper("foo");
assertNotNull(fooMapper);
assertThat(fooMapper, instanceOf(ObjectMapper.class));
Mapper barMapper = ((ObjectMapper) fooMapper).getMapper("bar");
assertNotNull(barMapper);
assertThat(barMapper, instanceOf(ObjectMapper.class));
Mapper bazMapper = ((ObjectMapper) barMapper).getMapper("baz");
assertNotNull(bazMapper);
assertThat(bazMapper, instanceOf(NumberFieldMapper.class));
}
public void testDynamicDottedFieldNameLongWithParentTemplate() throws Exception {
DocumentMapperParser mapperParser = createIndex("test").mapperService().documentMapperParser();
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
.startArray("dynamic_templates").startObject().startObject("georule")
.field("match", "foo*")
.startObject("mapping").field("type", "object").endObject()
.endObject().endObject().endArray().endObject().endObject().string();
DocumentMapper mapper = mapperParser.parse("type", new CompressedXContent(mapping));
BytesReference bytes = XContentFactory.jsonBuilder()
.startObject().field("foo.bar.baz", 0)
.endObject().bytes();
ParsedDocument doc = mapper.parse(SourceToParse.source("test", "type", "1", bytes, XContentType.JSON));
assertEquals(2, doc.rootDoc().getFields("foo.bar.baz").length);
Mapper fooMapper = doc.dynamicMappingsUpdate().root().getMapper("foo");
assertNotNull(fooMapper);
assertThat(fooMapper, instanceOf(ObjectMapper.class));
Mapper barMapper = ((ObjectMapper) fooMapper).getMapper("bar");
assertNotNull(barMapper);
assertThat(barMapper, instanceOf(ObjectMapper.class));
Mapper bazMapper = ((ObjectMapper) barMapper).getMapper("baz");
assertNotNull(bazMapper);
assertThat(bazMapper, instanceOf(NumberFieldMapper.class));
}
public void testDynamicDottedFieldNameLongWithExistingParent() throws Exception {
DocumentMapperParser mapperParser = createIndex("test").mapperService().documentMapperParser();
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
.startObject("properties") .startObject("foo")
.field("type", "object")
.endObject().endObject().endObject().endObject().string();
DocumentMapper mapper = mapperParser.parse("type", new CompressedXContent(mapping));
BytesReference bytes = XContentFactory.jsonBuilder()
.startObject().field("foo.bar.baz", 0)
.endObject().bytes();
ParsedDocument doc = mapper.parse(SourceToParse.source("test", "type", "1", bytes, XContentType.JSON));
assertEquals(2, doc.rootDoc().getFields("foo.bar.baz").length);
Mapper fooMapper = doc.dynamicMappingsUpdate().root().getMapper("foo");
assertNotNull(fooMapper);
assertThat(fooMapper, instanceOf(ObjectMapper.class));
Mapper barMapper = ((ObjectMapper) fooMapper).getMapper("bar");
assertNotNull(barMapper);
assertThat(barMapper, instanceOf(ObjectMapper.class));
Mapper bazMapper = ((ObjectMapper) barMapper).getMapper("baz");
assertNotNull(bazMapper);
assertThat(bazMapper, instanceOf(NumberFieldMapper.class));
}
public void testDynamicDottedFieldNameLongWithExistingParentWrongType() throws Exception {
DocumentMapperParser mapperParser = createIndex("test").mapperService().documentMapperParser();
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
.startObject("properties") .startObject("foo")
.field("type", "long")
.endObject().endObject().endObject().endObject().string();
DocumentMapper mapper = mapperParser.parse("type", new CompressedXContent(mapping));
BytesReference bytes = XContentFactory.jsonBuilder()
.startObject().field("foo.bar.baz", 0)
.endObject().bytes();
MapperParsingException exception = expectThrows(MapperParsingException.class,
() -> mapper.parse(SourceToParse.source("test", "type", "1", bytes, XContentType.JSON)));
assertEquals("Could not dynamically add mapping for field [foo.bar.baz]. "
+ "Existing mapping for [foo] must be of type object but found [long].", exception.getMessage());
}
public void testDynamicFalseDottedFieldNameLong() throws Exception {
DocumentMapperParser mapperParser = createIndex("test").mapperService().documentMapperParser();
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type").field("dynamic", "false")
.endObject().endObject().string();
DocumentMapper mapper = mapperParser.parse("type", new CompressedXContent(mapping));
BytesReference bytes = XContentFactory.jsonBuilder()
.startObject().field("foo.bar.baz", 0)
.endObject().bytes();
ParsedDocument doc = mapper.parse(SourceToParse.source("test", "type", "1", bytes, XContentType.JSON));
assertEquals(0, doc.rootDoc().getFields("foo.bar.baz").length);
}
public void testDynamicStrictDottedFieldNameLong() throws Exception {
DocumentMapperParser mapperParser = createIndex("test").mapperService().documentMapperParser();
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type").field("dynamic", "strict")
.endObject().endObject().string();
DocumentMapper mapper = mapperParser.parse("type", new CompressedXContent(mapping));
BytesReference bytes = XContentFactory.jsonBuilder()
.startObject().field("foo.bar.baz", 0)
.endObject().bytes();
StrictDynamicMappingException exception = expectThrows(StrictDynamicMappingException.class,
() -> mapper.parse(SourceToParse.source("test", "type", "1", bytes, XContentType.JSON)));
assertEquals("mapping set to strict, dynamic introduction of [foo] within [type] is not allowed", exception.getMessage());
}
public void testDynamicDottedFieldNameObject() throws Exception {
DocumentMapperParser mapperParser = createIndex("test").mapperService().documentMapperParser();
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
.endObject().endObject().string();
DocumentMapper mapper = mapperParser.parse("type", new CompressedXContent(mapping));
BytesReference bytes = XContentFactory.jsonBuilder()
.startObject().startObject("foo.bar.baz")
.field("a", 0)
.endObject().endObject().bytes();
ParsedDocument doc = mapper.parse(SourceToParse.source("test", "type", "1", bytes, XContentType.JSON));
assertEquals(2, doc.rootDoc().getFields("foo.bar.baz.a").length);
Mapper fooMapper = doc.dynamicMappingsUpdate().root().getMapper("foo");
assertNotNull(fooMapper);
assertThat(fooMapper, instanceOf(ObjectMapper.class));
Mapper barMapper = ((ObjectMapper) fooMapper).getMapper("bar");
assertNotNull(barMapper);
assertThat(barMapper, instanceOf(ObjectMapper.class));
Mapper bazMapper = ((ObjectMapper) barMapper).getMapper("baz");
assertNotNull(bazMapper);
assertThat(bazMapper, instanceOf(ObjectMapper.class));
Mapper aMapper = ((ObjectMapper) bazMapper).getMapper("a");
assertNotNull(aMapper);
assertThat(aMapper, instanceOf(NumberFieldMapper.class));
}
public void testDynamicDottedFieldNameObjectWithParentTemplate() throws Exception {
DocumentMapperParser mapperParser = createIndex("test").mapperService().documentMapperParser();
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
.startArray("dynamic_templates").startObject().startObject("georule")
.field("match", "foo*")
.startObject("mapping").field("type", "object").endObject()
.endObject().endObject().endArray().endObject().endObject().string();
DocumentMapper mapper = mapperParser.parse("type", new CompressedXContent(mapping));
BytesReference bytes = XContentFactory.jsonBuilder()
.startObject().startObject("foo.bar.baz")
.field("a", 0)
.endObject().endObject().bytes();
ParsedDocument doc = mapper.parse(SourceToParse.source("test", "type", "1", bytes, XContentType.JSON));
assertEquals(2, doc.rootDoc().getFields("foo.bar.baz.a").length);
Mapper fooMapper = doc.dynamicMappingsUpdate().root().getMapper("foo");
assertNotNull(fooMapper);
assertThat(fooMapper, instanceOf(ObjectMapper.class));
Mapper barMapper = ((ObjectMapper) fooMapper).getMapper("bar");
assertNotNull(barMapper);
assertThat(barMapper, instanceOf(ObjectMapper.class));
Mapper bazMapper = ((ObjectMapper) barMapper).getMapper("baz");
assertNotNull(bazMapper);
assertThat(bazMapper, instanceOf(ObjectMapper.class));
Mapper aMapper = ((ObjectMapper) bazMapper).getMapper("a");
assertNotNull(aMapper);
assertThat(aMapper, instanceOf(NumberFieldMapper.class));
}
public void testDynamicDottedFieldNameObjectWithExistingParent() throws Exception {
DocumentMapperParser mapperParser = createIndex("test").mapperService().documentMapperParser();
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type").startObject("properties").startObject("foo")
.field("type", "object").endObject().endObject().endObject().endObject().string();
DocumentMapper mapper = mapperParser.parse("type", new CompressedXContent(mapping));
BytesReference bytes = XContentFactory.jsonBuilder().startObject().startObject("foo.bar.baz").field("a", 0).endObject().endObject()
.bytes();
ParsedDocument doc = mapper.parse(SourceToParse.source("test", "type", "1", bytes, XContentType.JSON));
assertEquals(2, doc.rootDoc().getFields("foo.bar.baz.a").length);
Mapper fooMapper = doc.dynamicMappingsUpdate().root().getMapper("foo");
assertNotNull(fooMapper);
assertThat(fooMapper, instanceOf(ObjectMapper.class));
Mapper barMapper = ((ObjectMapper) fooMapper).getMapper("bar");
assertNotNull(barMapper);
assertThat(barMapper, instanceOf(ObjectMapper.class));
Mapper bazMapper = ((ObjectMapper) barMapper).getMapper("baz");
assertNotNull(bazMapper);
assertThat(bazMapper, instanceOf(ObjectMapper.class));
Mapper aMapper = ((ObjectMapper) bazMapper).getMapper("a");
assertNotNull(aMapper);
assertThat(aMapper, instanceOf(NumberFieldMapper.class));
}
public void testDynamicDottedFieldNameObjectWithExistingParentWrongType() throws Exception {
DocumentMapperParser mapperParser = createIndex("test").mapperService().documentMapperParser();
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
.startObject("properties") .startObject("foo")
.field("type", "long")
.endObject().endObject().endObject().endObject().string();
DocumentMapper mapper = mapperParser.parse("type", new CompressedXContent(mapping));
BytesReference bytes = XContentFactory.jsonBuilder().startObject().startObject("foo.bar.baz").field("a", 0).endObject().endObject()
.bytes();
MapperParsingException exception = expectThrows(MapperParsingException.class,
() -> mapper.parse(SourceToParse.source("test", "type", "1", bytes, XContentType.JSON)));
assertEquals("Could not dynamically add mapping for field [foo.bar.baz]. "
+ "Existing mapping for [foo] must be of type object but found [long].", exception.getMessage());
}
public void testDynamicFalseDottedFieldNameObject() throws Exception {
DocumentMapperParser mapperParser = createIndex("test").mapperService().documentMapperParser();
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type").field("dynamic", "false")
.endObject().endObject().string();
DocumentMapper mapper = mapperParser.parse("type", new CompressedXContent(mapping));
BytesReference bytes = XContentFactory.jsonBuilder()
.startObject().startObject("foo.bar.baz")
.field("a", 0)
.endObject().endObject().bytes();
ParsedDocument doc = mapper.parse(SourceToParse.source("test", "type", "1", bytes, XContentType.JSON));
assertEquals(0, doc.rootDoc().getFields("foo.bar.baz.a").length);
}
public void testDynamicStrictDottedFieldNameObject() throws Exception {
DocumentMapperParser mapperParser = createIndex("test").mapperService().documentMapperParser();
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type").field("dynamic", "strict")
.endObject().endObject().string();
DocumentMapper mapper = mapperParser.parse("type", new CompressedXContent(mapping));
BytesReference bytes = XContentFactory.jsonBuilder()
.startObject().startObject("foo.bar.baz")
.field("a", 0)
.endObject().endObject().bytes();
StrictDynamicMappingException exception = expectThrows(StrictDynamicMappingException.class,
() -> mapper.parse(SourceToParse.source("test", "type", "1", bytes, XContentType.JSON)));
assertEquals("mapping set to strict, dynamic introduction of [foo] within [type] is not allowed", exception.getMessage());
}
public void testDocumentContainsMetadataField() throws Exception {
DocumentMapperParser mapperParser = createIndex("test").mapperService().documentMapperParser();
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type").endObject().endObject().string();
DocumentMapper mapper = mapperParser.parse("type", new CompressedXContent(mapping));
BytesReference bytes = XContentFactory.jsonBuilder().startObject().field("_ttl", 0).endObject().bytes();
MapperParsingException e = expectThrows(MapperParsingException.class, () ->
mapper.parse(SourceToParse.source("test", "type", "1", bytes, XContentType.JSON)));
assertTrue(e.getMessage(), e.getMessage().contains("cannot be added inside a document"));
BytesReference bytes2 = XContentFactory.jsonBuilder().startObject().field("foo._ttl", 0).endObject().bytes();
mapper.parse(SourceToParse.source("test", "type", "1", bytes2, XContentType.JSON)); // parses without error
}
public void testSimpleMapper() throws Exception {
IndexService indexService = createIndex("test");
DocumentMapper docMapper = new DocumentMapper.Builder(
new RootObjectMapper.Builder("person")
.add(new ObjectMapper.Builder("name").add(new TextFieldMapper.Builder("first").store(true).index(false))),
indexService.mapperService()).build(indexService.mapperService());
BytesReference json = new BytesArray(copyToBytesFromClasspath("/org/elasticsearch/index/mapper/simple/test1.json"));
Document doc = docMapper.parse(SourceToParse.source("test", "person", "1", json, XContentType.JSON)).rootDoc();
assertThat(doc.get(docMapper.mappers().getMapper("name.first").fieldType().name()), equalTo("shay"));
doc = docMapper.parse(SourceToParse.source("test", "person", "1", json, XContentType.JSON)).rootDoc();
}
public void testParseToJsonAndParse() throws Exception {
String mapping = copyToStringFromClasspath("/org/elasticsearch/index/mapper/simple/test-mapping.json");
DocumentMapperParser parser = createIndex("test").mapperService().documentMapperParser();
DocumentMapper docMapper = parser.parse("person", new CompressedXContent(mapping));
String builtMapping = docMapper.mappingSource().string();
// reparse it
DocumentMapper builtDocMapper = parser.parse("person", new CompressedXContent(builtMapping));
BytesReference json = new BytesArray(copyToBytesFromClasspath("/org/elasticsearch/index/mapper/simple/test1.json"));
Document doc = builtDocMapper.parse(SourceToParse.source("test", "person", "1", json, XContentType.JSON)).rootDoc();
assertThat(doc.get(docMapper.idFieldMapper().fieldType().name()), equalTo("1"));
assertThat(doc.get(docMapper.mappers().getMapper("name.first").fieldType().name()), equalTo("shay"));
}
public void testSimpleParser() throws Exception {
String mapping = copyToStringFromClasspath("/org/elasticsearch/index/mapper/simple/test-mapping.json");
DocumentMapper docMapper = createIndex("test").mapperService().documentMapperParser().parse("person", new CompressedXContent(mapping));
assertThat((String) docMapper.meta().get("param1"), equalTo("value1"));
BytesReference json = new BytesArray(copyToBytesFromClasspath("/org/elasticsearch/index/mapper/simple/test1.json"));
Document doc = docMapper.parse(SourceToParse.source("test", "person", "1", json, XContentType.JSON)).rootDoc();
assertThat(doc.get(docMapper.idFieldMapper().fieldType().name()), equalTo("1"));
assertThat(doc.get(docMapper.mappers().getMapper("name.first").fieldType().name()), equalTo("shay"));
}
public void testSimpleParserNoTypeNoId() throws Exception {
String mapping = copyToStringFromClasspath("/org/elasticsearch/index/mapper/simple/test-mapping.json");
DocumentMapper docMapper = createIndex("test").mapperService().documentMapperParser().parse("person", new CompressedXContent(mapping));
BytesReference json = new BytesArray(copyToBytesFromClasspath("/org/elasticsearch/index/mapper/simple/test1-notype-noid.json"));
Document doc = docMapper.parse(SourceToParse.source("test", "person", "1", json, XContentType.JSON)).rootDoc();
assertThat(doc.get(docMapper.idFieldMapper().fieldType().name()), equalTo("1"));
assertThat(doc.get(docMapper.mappers().getMapper("name.first").fieldType().name()), equalTo("shay"));
}
public void testAttributes() throws Exception {
String mapping = copyToStringFromClasspath("/org/elasticsearch/index/mapper/simple/test-mapping.json");
DocumentMapperParser parser = createIndex("test").mapperService().documentMapperParser();
DocumentMapper docMapper = parser.parse("person", new CompressedXContent(mapping));
assertThat((String) docMapper.meta().get("param1"), equalTo("value1"));
String builtMapping = docMapper.mappingSource().string();
DocumentMapper builtDocMapper = parser.parse("person", new CompressedXContent(builtMapping));
assertThat((String) builtDocMapper.meta().get("param1"), equalTo("value1"));
}
public void testNoDocumentSent() throws Exception {
IndexService indexService = createIndex("test");
DocumentMapper docMapper = new DocumentMapper.Builder(
new RootObjectMapper.Builder("person")
.add(new ObjectMapper.Builder("name").add(new TextFieldMapper.Builder("first").store(true).index(false))),
indexService.mapperService()).build(indexService.mapperService());
BytesReference json = new BytesArray("".getBytes(StandardCharsets.UTF_8));
try {
docMapper.parse(SourceToParse.source("test", "person", "1", json, XContentType.JSON)).rootDoc();
fail("this point is never reached");
} catch (MapperParsingException e) {
assertThat(e.getMessage(), equalTo("failed to parse, document is empty"));
}
}
public void testNoLevel() throws Exception {
String defaultMapping = XContentFactory.jsonBuilder().startObject().startObject("type").endObject().endObject().string();
DocumentMapper defaultMapper = createIndex("test").mapperService().documentMapperParser().parse("type", new CompressedXContent(defaultMapping));
ParsedDocument doc = defaultMapper.parse(SourceToParse.source("test", "type", "1", XContentFactory.jsonBuilder()
.startObject()
.field("test1", "value1")
.field("test2", "value2")
.startObject("inner").field("inner_field", "inner_value").endObject()
.endObject()
.bytes(),
XContentType.JSON));
assertThat(doc.rootDoc().get("test1"), equalTo("value1"));
assertThat(doc.rootDoc().get("test2"), equalTo("value2"));
assertThat(doc.rootDoc().get("inner.inner_field"), equalTo("inner_value"));
}
public void testTypeLevel() throws Exception {
String defaultMapping = XContentFactory.jsonBuilder().startObject().startObject("type").endObject().endObject().string();
DocumentMapper defaultMapper = createIndex("test").mapperService().documentMapperParser().parse("type", new CompressedXContent(defaultMapping));
ParsedDocument doc = defaultMapper.parse(SourceToParse.source("test", "type", "1", XContentFactory.jsonBuilder()
.startObject().startObject("type")
.field("test1", "value1")
.field("test2", "value2")
.startObject("inner").field("inner_field", "inner_value").endObject()
.endObject().endObject()
.bytes(),
XContentType.JSON));
assertThat(doc.rootDoc().get("type.test1"), equalTo("value1"));
assertThat(doc.rootDoc().get("type.test2"), equalTo("value2"));
assertThat(doc.rootDoc().get("type.inner.inner_field"), equalTo("inner_value"));
}
public void testNoLevelWithFieldTypeAsValue() throws Exception {
String defaultMapping = XContentFactory.jsonBuilder().startObject().startObject("type").endObject().endObject().string();
DocumentMapper defaultMapper = createIndex("test").mapperService().documentMapperParser().parse("type", new CompressedXContent(defaultMapping));
ParsedDocument doc = defaultMapper.parse(SourceToParse.source("test", "type", "1", XContentFactory.jsonBuilder()
.startObject()
.field("type", "value_type")
.field("test1", "value1")
.field("test2", "value2")
.startObject("inner").field("inner_field", "inner_value").endObject()
.endObject()
.bytes(),
XContentType.JSON));
assertThat(doc.rootDoc().get("type"), equalTo("value_type"));
assertThat(doc.rootDoc().get("test1"), equalTo("value1"));
assertThat(doc.rootDoc().get("test2"), equalTo("value2"));
assertThat(doc.rootDoc().get("inner.inner_field"), equalTo("inner_value"));
}
public void testTypeLevelWithFieldTypeAsValue() throws Exception {
String defaultMapping = XContentFactory.jsonBuilder().startObject().startObject("type").endObject().endObject().string();
DocumentMapper defaultMapper = createIndex("test").mapperService().documentMapperParser().parse("type", new CompressedXContent(defaultMapping));
ParsedDocument doc = defaultMapper.parse(SourceToParse.source("test", "type", "1", XContentFactory.jsonBuilder()
.startObject().startObject("type")
.field("type", "value_type")
.field("test1", "value1")
.field("test2", "value2")
.startObject("inner").field("inner_field", "inner_value").endObject()
.endObject().endObject()
.bytes(),
XContentType.JSON));
assertThat(doc.rootDoc().get("type.type"), equalTo("value_type"));
assertThat(doc.rootDoc().get("type.test1"), equalTo("value1"));
assertThat(doc.rootDoc().get("type.test2"), equalTo("value2"));
assertThat(doc.rootDoc().get("type.inner.inner_field"), equalTo("inner_value"));
}
public void testNoLevelWithFieldTypeAsObject() throws Exception {
String defaultMapping = XContentFactory.jsonBuilder().startObject().startObject("type").endObject().endObject().string();
DocumentMapper defaultMapper = createIndex("test").mapperService().documentMapperParser().parse("type", new CompressedXContent(defaultMapping));
ParsedDocument doc = defaultMapper.parse(SourceToParse.source("test", "type", "1", XContentFactory.jsonBuilder()
.startObject()
.startObject("type").field("type_field", "type_value").endObject()
.field("test1", "value1")
.field("test2", "value2")
.startObject("inner").field("inner_field", "inner_value").endObject()
.endObject()
.bytes(),
XContentType.JSON));
// in this case, we analyze the type object as the actual document, and ignore the other same level fields
assertThat(doc.rootDoc().get("type.type_field"), equalTo("type_value"));
assertThat(doc.rootDoc().get("test1"), equalTo("value1"));
assertThat(doc.rootDoc().get("test2"), equalTo("value2"));
}
public void testTypeLevelWithFieldTypeAsObject() throws Exception {
String defaultMapping = XContentFactory.jsonBuilder().startObject().startObject("type").endObject().endObject().string();
DocumentMapper defaultMapper = createIndex("test").mapperService().documentMapperParser().parse("type", new CompressedXContent(defaultMapping));
ParsedDocument doc = defaultMapper.parse(SourceToParse.source("test", "type", "1", XContentFactory.jsonBuilder()
.startObject().startObject("type")
.startObject("type").field("type_field", "type_value").endObject()
.field("test1", "value1")
.field("test2", "value2")
.startObject("inner").field("inner_field", "inner_value").endObject()
.endObject().endObject()
.bytes(),
XContentType.JSON));
assertThat(doc.rootDoc().get("type.type.type_field"), equalTo("type_value"));
assertThat(doc.rootDoc().get("type.test1"), equalTo("value1"));
assertThat(doc.rootDoc().get("type.test2"), equalTo("value2"));
assertThat(doc.rootDoc().get("type.inner.inner_field"), equalTo("inner_value"));
}
public void testNoLevelWithFieldTypeAsValueNotFirst() throws Exception {
String defaultMapping = XContentFactory.jsonBuilder().startObject().startObject("type").endObject().endObject().string();
DocumentMapper defaultMapper = createIndex("test").mapperService().documentMapperParser().parse("type", new CompressedXContent(defaultMapping));
ParsedDocument doc = defaultMapper.parse(SourceToParse.source("test", "type", "1", XContentFactory.jsonBuilder()
.startObject().startObject("type")
.field("test1", "value1")
.field("test2", "value2")
.field("type", "value_type")
.startObject("inner").field("inner_field", "inner_value").endObject()
.endObject().endObject()
.bytes(),
XContentType.JSON));
assertThat(doc.rootDoc().get("type.type"), equalTo("value_type"));
assertThat(doc.rootDoc().get("type.test1"), equalTo("value1"));
assertThat(doc.rootDoc().get("type.test2"), equalTo("value2"));
assertThat(doc.rootDoc().get("type.inner.inner_field"), equalTo("inner_value"));
}
public void testTypeLevelWithFieldTypeAsValueNotFirst() throws Exception {
String defaultMapping = XContentFactory.jsonBuilder().startObject().startObject("type").endObject().endObject().string();
DocumentMapper defaultMapper = createIndex("test").mapperService().documentMapperParser().parse("type", new CompressedXContent(defaultMapping));
ParsedDocument doc = defaultMapper.parse(SourceToParse.source("test", "type", "1", XContentFactory.jsonBuilder()
.startObject().startObject("type")
.field("test1", "value1")
.field("type", "value_type")
.field("test2", "value2")
.startObject("inner").field("inner_field", "inner_value").endObject()
.endObject().endObject()
.bytes(),
XContentType.JSON));
assertThat(doc.rootDoc().get("type.type"), equalTo("value_type"));
assertThat(doc.rootDoc().get("type.test1"), equalTo("value1"));
assertThat(doc.rootDoc().get("type.test2"), equalTo("value2"));
assertThat(doc.rootDoc().get("type.inner.inner_field"), equalTo("inner_value"));
}
public void testNoLevelWithFieldTypeAsObjectNotFirst() throws Exception {
String defaultMapping = XContentFactory.jsonBuilder().startObject().startObject("type").endObject().endObject().string();
DocumentMapper defaultMapper = createIndex("test").mapperService().documentMapperParser().parse("type", new CompressedXContent(defaultMapping));
ParsedDocument doc = defaultMapper.parse(SourceToParse.source("test", "type", "1", XContentFactory.jsonBuilder()
.startObject()
.field("test1", "value1")
.startObject("type").field("type_field", "type_value").endObject()
.field("test2", "value2")
.startObject("inner").field("inner_field", "inner_value").endObject()
.endObject()
.bytes(),
XContentType.JSON));
// when the type is not the first one, we don't confuse it...
assertThat(doc.rootDoc().get("type.type_field"), equalTo("type_value"));
assertThat(doc.rootDoc().get("test1"), equalTo("value1"));
assertThat(doc.rootDoc().get("test2"), equalTo("value2"));
assertThat(doc.rootDoc().get("inner.inner_field"), equalTo("inner_value"));
}
public void testTypeLevelWithFieldTypeAsObjectNotFirst() throws Exception {
String defaultMapping = XContentFactory.jsonBuilder().startObject().startObject("type").endObject().endObject().string();
DocumentMapper defaultMapper = createIndex("test").mapperService().documentMapperParser().parse("type", new CompressedXContent(defaultMapping));
ParsedDocument doc = defaultMapper.parse(SourceToParse.source("test", "type", "1", XContentFactory.jsonBuilder()
.startObject().startObject("type")
.field("test1", "value1")
.startObject("type").field("type_field", "type_value").endObject()
.field("test2", "value2")
.startObject("inner").field("inner_field", "inner_value").endObject()
.endObject().endObject()
.bytes(),
XContentType.JSON));
assertThat(doc.rootDoc().get("type.type.type_field"), equalTo("type_value"));
assertThat(doc.rootDoc().get("type.test1"), equalTo("value1"));
assertThat(doc.rootDoc().get("type.test2"), equalTo("value2"));
assertThat(doc.rootDoc().get("type.inner.inner_field"), equalTo("inner_value"));
}
public void testDynamicDateDetectionDisabledOnNumbers() throws IOException {
DocumentMapperParser mapperParser = createIndex("test").mapperService().documentMapperParser();
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
.startArray("dynamic_date_formats")
.value("yyyy")
.endArray().endObject().endObject().string();
DocumentMapper mapper = mapperParser.parse("type", new CompressedXContent(mapping));
BytesReference bytes = XContentFactory.jsonBuilder()
.startObject()
.field("foo", "2016")
.endObject().bytes();
// Even though we matched the dynamic format, we do not match on numbers,
// which are too likely to be false positives
ParsedDocument doc = mapper.parse(SourceToParse.source("test", "type", "1", bytes, XContentType.JSON));
Mapping update = doc.dynamicMappingsUpdate();
assertNotNull(update);
Mapper dateMapper = update.root().getMapper("foo");
assertNotNull(dateMapper);
assertThat(dateMapper, not(instanceOf(DateFieldMapper.class)));
}
public void testDynamicDateDetectionEnabledWithNoSpecialCharacters() throws IOException {
DocumentMapperParser mapperParser = createIndex("test").mapperService().documentMapperParser();
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
.startArray("dynamic_date_formats")
.value("yyyy MM")
.endArray().endObject().endObject().string();
DocumentMapper mapper = mapperParser.parse("type", new CompressedXContent(mapping));
BytesReference bytes = XContentFactory.jsonBuilder()
.startObject()
.field("foo", "2016 12")
.endObject().bytes();
// We should have generated a date field
ParsedDocument doc = mapper.parse(SourceToParse.source("test", "type", "1", bytes, XContentType.JSON));
Mapping update = doc.dynamicMappingsUpdate();
assertNotNull(update);
Mapper dateMapper = update.root().getMapper("foo");
assertNotNull(dateMapper);
assertThat(dateMapper, instanceOf(DateFieldMapper.class));
}
public void testDynamicFieldsStartingAndEndingWithDot() throws Exception {
BytesReference bytes = XContentFactory.jsonBuilder().startObject().startArray("top.")
.startObject().startArray("foo.")
.startObject()
.field("thing", "bah")
.endObject().endArray()
.endObject().endArray()
.endObject().bytes();
client().prepareIndex("idx", "type").setSource(bytes, XContentType.JSON).get();
bytes = XContentFactory.jsonBuilder().startObject().startArray("top.")
.startObject().startArray("foo.")
.startObject()
.startObject("bar.")
.startObject("aoeu")
.field("a", 1).field("b", 2)
.endObject()
.endObject()
.endObject()
.endArray().endObject().endArray()
.endObject().bytes();
try {
client().prepareIndex("idx", "type").setSource(bytes, XContentType.JSON).get();
fail("should have failed to dynamically introduce a double-dot field");
} catch (IllegalArgumentException e) {
assertThat(e.getMessage(),
containsString("object field starting or ending with a [.] makes object resolution ambiguous: [top..foo..bar]"));
}
}
}