|
19 | 19 |
|
20 | 20 | package org.elasticsearch.index.mapper; |
21 | 21 |
|
22 | | -import java.io.IOException; |
23 | | -import java.nio.charset.StandardCharsets; |
24 | | -import java.util.ArrayList; |
25 | | -import java.util.Arrays; |
26 | | -import java.util.Collection; |
27 | | -import java.util.Collections; |
28 | | -import java.util.HashSet; |
29 | | -import java.util.List; |
30 | | -import java.util.Set; |
31 | | - |
32 | 22 | import org.apache.lucene.index.IndexableField; |
33 | | -import org.elasticsearch.common.bytes.BytesArray; |
34 | 23 | import org.elasticsearch.Version; |
35 | 24 | import org.elasticsearch.cluster.metadata.IndexMetaData; |
| 25 | +import org.elasticsearch.common.bytes.BytesArray; |
36 | 26 | import org.elasticsearch.common.bytes.BytesReference; |
37 | 27 | import org.elasticsearch.common.compress.CompressedXContent; |
38 | | -import org.elasticsearch.common.lucene.all.AllField; |
39 | 28 | import org.elasticsearch.common.settings.Settings; |
| 29 | +import org.elasticsearch.common.xcontent.XContentBuilder; |
40 | 30 | import org.elasticsearch.common.xcontent.XContentFactory; |
| 31 | +import org.elasticsearch.common.xcontent.XContentType; |
41 | 32 | import org.elasticsearch.index.IndexService; |
42 | 33 | import org.elasticsearch.index.mapper.ParseContext.Document; |
43 | 34 | import org.elasticsearch.plugins.Plugin; |
44 | 35 | import org.elasticsearch.test.ESSingleNodeTestCase; |
45 | 36 | import org.elasticsearch.test.InternalSettingsPlugin; |
46 | 37 |
|
| 38 | +import java.io.IOException; |
| 39 | +import java.nio.charset.StandardCharsets; |
| 40 | +import java.util.ArrayList; |
| 41 | +import java.util.Arrays; |
| 42 | +import java.util.Collection; |
| 43 | +import java.util.Collections; |
| 44 | +import java.util.HashSet; |
| 45 | +import java.util.List; |
| 46 | +import java.util.Set; |
| 47 | + |
47 | 48 | import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder; |
48 | 49 | import static org.elasticsearch.test.StreamsUtils.copyToBytesFromClasspath; |
49 | 50 | import static org.elasticsearch.test.StreamsUtils.copyToStringFromClasspath; |
@@ -166,6 +167,92 @@ public void testDotsWithDynamicNestedMapper() throws Exception { |
166 | 167 | e.getMessage()); |
167 | 168 | } |
168 | 169 |
|
| 170 | + public void testNestedHaveIdAndTypeFields() throws Exception { |
| 171 | + DocumentMapperParser mapperParser1 = createIndex("index1", Settings.builder() |
| 172 | + .put("index.mapping.single_type", false).build() |
| 173 | + ).mapperService().documentMapperParser(); |
| 174 | + DocumentMapperParser mapperParser2 = createIndex("index2", Settings.builder() |
| 175 | + .put("index.mapping.single_type", true).build() |
| 176 | + ).mapperService().documentMapperParser(); |
| 177 | + |
| 178 | + XContentBuilder mapping = XContentFactory.jsonBuilder().startObject().startObject("type").startObject("properties"); |
| 179 | + { |
| 180 | + mapping.startObject("foo"); |
| 181 | + mapping.field("type", "nested"); |
| 182 | + { |
| 183 | + mapping.startObject("properties"); |
| 184 | + { |
| 185 | + |
| 186 | + mapping.startObject("bar"); |
| 187 | + mapping.field("type", "keyword"); |
| 188 | + mapping.endObject(); |
| 189 | + } |
| 190 | + mapping.endObject(); |
| 191 | + } |
| 192 | + mapping.endObject(); |
| 193 | + } |
| 194 | + { |
| 195 | + mapping.startObject("baz"); |
| 196 | + mapping.field("type", "keyword"); |
| 197 | + mapping.endObject(); |
| 198 | + } |
| 199 | + mapping.endObject().endObject().endObject(); |
| 200 | + DocumentMapper mapper1 = mapperParser1.parse("type", new CompressedXContent(mapping.string())); |
| 201 | + DocumentMapper mapper2 = mapperParser2.parse("type", new CompressedXContent(mapping.string())); |
| 202 | + |
| 203 | + XContentBuilder doc = XContentFactory.jsonBuilder().startObject(); |
| 204 | + { |
| 205 | + doc.startArray("foo"); |
| 206 | + { |
| 207 | + doc.startObject(); |
| 208 | + doc.field("bar", "value1"); |
| 209 | + doc.endObject(); |
| 210 | + } |
| 211 | + doc.endArray(); |
| 212 | + doc.field("baz", "value2"); |
| 213 | + } |
| 214 | + doc.endObject(); |
| 215 | + |
| 216 | + // Verify in the case where multiple types are allowed that the _uid field is added to nested documents: |
| 217 | + ParsedDocument result = mapper1.parse(SourceToParse.source("index1", "type", "1", doc.bytes(), XContentType.JSON)); |
| 218 | + assertEquals(2, result.docs().size()); |
| 219 | + // Nested document: |
| 220 | + assertNull(result.docs().get(0).getField(IdFieldMapper.NAME)); |
| 221 | + assertNotNull(result.docs().get(0).getField(UidFieldMapper.NAME)); |
| 222 | + assertEquals("type#1", result.docs().get(0).getField(UidFieldMapper.NAME).stringValue()); |
| 223 | + assertEquals(UidFieldMapper.Defaults.NESTED_FIELD_TYPE, result.docs().get(0).getField(UidFieldMapper.NAME).fieldType()); |
| 224 | + assertNotNull(result.docs().get(0).getField(TypeFieldMapper.NAME)); |
| 225 | + assertEquals("__foo", result.docs().get(0).getField(TypeFieldMapper.NAME).stringValue()); |
| 226 | + assertEquals("value1", result.docs().get(0).getField("foo.bar").binaryValue().utf8ToString()); |
| 227 | + // Root document: |
| 228 | + assertNull(result.docs().get(1).getField(IdFieldMapper.NAME)); |
| 229 | + assertNotNull(result.docs().get(1).getField(UidFieldMapper.NAME)); |
| 230 | + assertEquals("type#1", result.docs().get(1).getField(UidFieldMapper.NAME).stringValue()); |
| 231 | + assertEquals(UidFieldMapper.Defaults.FIELD_TYPE, result.docs().get(1).getField(UidFieldMapper.NAME).fieldType()); |
| 232 | + assertNotNull(result.docs().get(1).getField(TypeFieldMapper.NAME)); |
| 233 | + assertEquals("type", result.docs().get(1).getField(TypeFieldMapper.NAME).stringValue()); |
| 234 | + assertEquals("value2", result.docs().get(1).getField("baz").binaryValue().utf8ToString()); |
| 235 | + |
| 236 | + // Verify in the case where only a single type is allowed that the _id field is added to nested documents: |
| 237 | + result = mapper2.parse(SourceToParse.source("index2", "type", "1", doc.bytes(), XContentType.JSON)); |
| 238 | + assertEquals(2, result.docs().size()); |
| 239 | + // Nested document: |
| 240 | + assertNull(result.docs().get(0).getField(UidFieldMapper.NAME)); |
| 241 | + assertNotNull(result.docs().get(0).getField(IdFieldMapper.NAME)); |
| 242 | + assertEquals("1", result.docs().get(0).getField(IdFieldMapper.NAME).stringValue()); |
| 243 | + assertEquals(IdFieldMapper.Defaults.NESTED_FIELD_TYPE, result.docs().get(0).getField(IdFieldMapper.NAME).fieldType()); |
| 244 | + assertNotNull(result.docs().get(0).getField(TypeFieldMapper.NAME)); |
| 245 | + assertEquals("__foo", result.docs().get(0).getField(TypeFieldMapper.NAME).stringValue()); |
| 246 | + assertEquals("value1", result.docs().get(0).getField("foo.bar").binaryValue().utf8ToString()); |
| 247 | + // Root document: |
| 248 | + assertNull(result.docs().get(1).getField(UidFieldMapper.NAME)); |
| 249 | + assertNotNull(result.docs().get(1).getField(IdFieldMapper.NAME)); |
| 250 | + assertEquals("1", result.docs().get(1).getField(IdFieldMapper.NAME).stringValue()); |
| 251 | + assertEquals(IdFieldMapper.Defaults.FIELD_TYPE, result.docs().get(1).getField(IdFieldMapper.NAME).fieldType()); |
| 252 | + assertNull(result.docs().get(1).getField(TypeFieldMapper.NAME)); |
| 253 | + assertEquals("value2", result.docs().get(1).getField("baz").binaryValue().utf8ToString()); |
| 254 | + } |
| 255 | + |
169 | 256 | public void testPropagateDynamicWithExistingMapper() throws Exception { |
170 | 257 | DocumentMapperParser mapperParser = createIndex("test").mapperService().documentMapperParser(); |
171 | 258 | String mapping = XContentFactory.jsonBuilder().startObject().startObject("type") |
@@ -657,7 +744,8 @@ public void testDynamicDottedFieldNameLongArrayWithExistingParentWrongType() thr |
657 | 744 | .value(0) |
658 | 745 | .value(1) |
659 | 746 | .endArray().endObject().bytes(); |
660 | | - MapperParsingException exception = expectThrows(MapperParsingException.class, () -> mapper.parse("test", "type", "1", bytes)); |
| 747 | + MapperParsingException exception = expectThrows(MapperParsingException.class, |
| 748 | + () -> mapper.parse("test", "type", "1", bytes)); |
661 | 749 | assertEquals("Could not dynamically add mapping for field [foo.bar.baz]. " |
662 | 750 | + "Existing mapping for [foo] must be of type object but found [long].", exception.getMessage()); |
663 | 751 | } |
@@ -775,7 +863,8 @@ public void testDynamicDottedFieldNameLongWithExistingParentWrongType() throws E |
775 | 863 | BytesReference bytes = XContentFactory.jsonBuilder() |
776 | 864 | .startObject().field("foo.bar.baz", 0) |
777 | 865 | .endObject().bytes(); |
778 | | - MapperParsingException exception = expectThrows(MapperParsingException.class, () -> mapper.parse("test", "type", "1", bytes)); |
| 866 | + MapperParsingException exception = expectThrows(MapperParsingException.class, |
| 867 | + () -> mapper.parse("test", "type", "1", bytes)); |
779 | 868 | assertEquals("Could not dynamically add mapping for field [foo.bar.baz]. " |
780 | 869 | + "Existing mapping for [foo] must be of type object but found [long].", exception.getMessage()); |
781 | 870 | } |
@@ -896,7 +985,8 @@ public void testDynamicDottedFieldNameObjectWithExistingParentWrongType() throws |
896 | 985 |
|
897 | 986 | BytesReference bytes = XContentFactory.jsonBuilder().startObject().startObject("foo.bar.baz").field("a", 0).endObject().endObject() |
898 | 987 | .bytes(); |
899 | | - MapperParsingException exception = expectThrows(MapperParsingException.class, () -> mapper.parse("test", "type", "1", bytes)); |
| 988 | + MapperParsingException exception = expectThrows(MapperParsingException.class, |
| 989 | + () -> mapper.parse("test", "type", "1", bytes)); |
900 | 990 | assertEquals("Could not dynamically add mapping for field [foo.bar.baz]. " |
901 | 991 | + "Existing mapping for [foo] must be of type object but found [long].", exception.getMessage()); |
902 | 992 | } |
|
0 commit comments