|
@@ -20,13 +20,17 @@ import org.elasticsearch.cluster.ClusterStateUpdateTask;
|
|
|
import org.elasticsearch.cluster.metadata.MappingMetadata;
|
|
|
import org.elasticsearch.cluster.service.ClusterService;
|
|
|
import org.elasticsearch.common.Randomness;
|
|
|
+import org.elasticsearch.common.Strings;
|
|
|
import org.elasticsearch.common.geo.GeoPoint;
|
|
|
import org.elasticsearch.common.settings.Settings;
|
|
|
-import org.elasticsearch.core.TimeValue;
|
|
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
|
|
import org.elasticsearch.common.xcontent.XContentFactory;
|
|
|
+import org.elasticsearch.common.xcontent.XContentType;
|
|
|
+import org.elasticsearch.common.xcontent.support.XContentMapValues;
|
|
|
+import org.elasticsearch.core.TimeValue;
|
|
|
import org.elasticsearch.index.query.GeoBoundingBoxQueryBuilder;
|
|
|
import org.elasticsearch.plugins.Plugin;
|
|
|
+import org.elasticsearch.rest.RestStatus;
|
|
|
import org.elasticsearch.test.ESIntegTestCase;
|
|
|
import org.elasticsearch.test.InternalSettingsPlugin;
|
|
|
import org.hamcrest.Matchers;
|
|
@@ -44,6 +48,8 @@ import static org.elasticsearch.index.mapper.MapperService.INDEX_MAPPING_DEPTH_L
|
|
|
import static org.elasticsearch.index.mapper.MapperService.INDEX_MAPPING_TOTAL_FIELDS_LIMIT_SETTING;
|
|
|
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
|
|
|
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSearchHits;
|
|
|
+import static org.hamcrest.Matchers.contains;
|
|
|
+import static org.hamcrest.Matchers.containsInAnyOrder;
|
|
|
import static org.hamcrest.Matchers.containsString;
|
|
|
import static org.hamcrest.Matchers.equalTo;
|
|
|
import static org.hamcrest.Matchers.instanceOf;
|
|
@@ -327,4 +333,78 @@ public class DynamicMappingIT extends ESIntegTestCase {
|
|
|
assertThat(bulkItemResponses.getItems()[1].getFailureMessage(),
|
|
|
containsString("Can't find dynamic template for dynamic template name [bar_foo] of field [address.location]"));
|
|
|
}
|
|
|
+
|
|
|
+ public void testDynamicRuntimeNoConflicts() {
|
|
|
+ assertAcked(client().admin().indices().prepareCreate("test").setMapping("{\"_doc\":{\"dynamic\":\"runtime\"}}").get());
|
|
|
+
|
|
|
+ List<IndexRequest> docs = new ArrayList<>();
|
|
|
+ docs.add(new IndexRequest("test").source("one.two.three", new int[]{1, 2, 3}));
|
|
|
+ docs.add(new IndexRequest("test").source("one.two", 1.2));
|
|
|
+ docs.add(new IndexRequest("test").source("one", "one"));
|
|
|
+ docs.add(new IndexRequest("test").source("{\"one\":{\"two\": { \"three\": \"three\"}}}", XContentType.JSON));
|
|
|
+ Collections.shuffle(docs, random());
|
|
|
+ BulkRequest bulkRequest = new BulkRequest();
|
|
|
+ for (IndexRequest doc : docs) {
|
|
|
+ bulkRequest.add(doc);
|
|
|
+ }
|
|
|
+ BulkResponse bulkItemResponses = client().bulk(bulkRequest).actionGet();
|
|
|
+ assertFalse(bulkItemResponses.buildFailureMessage(), bulkItemResponses.hasFailures());
|
|
|
+
|
|
|
+ GetMappingsResponse getMappingsResponse = client().admin().indices().prepareGetMappings("test").get();
|
|
|
+ Map<String, Object> sourceAsMap = getMappingsResponse.getMappings().get("test").sourceAsMap();
|
|
|
+ assertFalse(sourceAsMap.containsKey("properties"));
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
+ Map<String, Object> runtime = (Map<String, Object>)sourceAsMap.get("runtime");
|
|
|
+ //depending on the order of the documents field types may differ, but there are no mapping conflicts
|
|
|
+ assertThat(runtime.keySet(), containsInAnyOrder("one", "one.two", "one.two.three"));
|
|
|
+ }
|
|
|
+
|
|
|
+ public void testDynamicRuntimeObjectFields() {
|
|
|
+ assertAcked(client().admin().indices().prepareCreate("test").setMapping("{\"_doc\":{\"properties\":{" +
|
|
|
+ "\"obj\":{\"properties\":{\"runtime\":{\"type\":\"object\",\"dynamic\":\"runtime\"}}}}}}").get());
|
|
|
+
|
|
|
+ List<IndexRequest> docs = new ArrayList<>();
|
|
|
+ docs.add(new IndexRequest("test").source("obj.one", 1));
|
|
|
+ docs.add(new IndexRequest("test").source("anything", 1));
|
|
|
+ docs.add(new IndexRequest("test").source("obj.runtime.one.two", "test"));
|
|
|
+ docs.add(new IndexRequest("test").source("obj.runtime.one", "one"));
|
|
|
+ docs.add(new IndexRequest("test").source("{\"obj\":{\"runtime\":{\"one\":{\"two\": \"test\"}}}}", XContentType.JSON));
|
|
|
+ Collections.shuffle(docs, random());
|
|
|
+ BulkRequest bulkRequest = new BulkRequest();
|
|
|
+ for (IndexRequest doc : docs) {
|
|
|
+ bulkRequest.add(doc);
|
|
|
+ }
|
|
|
+ BulkResponse bulkItemResponses = client().bulk(bulkRequest).actionGet();
|
|
|
+ assertFalse(bulkItemResponses.buildFailureMessage(), bulkItemResponses.hasFailures());
|
|
|
+
|
|
|
+ MapperParsingException exception = expectThrows(MapperParsingException.class,
|
|
|
+ () -> client().prepareIndex("test").setSource("obj.runtime", "value").get());
|
|
|
+ assertEquals("object mapping for [obj.runtime] tried to parse field [obj.runtime] as object, but found a concrete value",
|
|
|
+ exception.getMessage());
|
|
|
+
|
|
|
+ assertEquals("{\"test\":{\"mappings\":" +
|
|
|
+ "{\"runtime\":{\"obj.runtime.one\":{\"type\":\"keyword\"},\"obj.runtime.one.two\":{\"type\":\"keyword\"}}," +
|
|
|
+ "\"properties\":{\"anything\":{\"type\":\"long\"}," +
|
|
|
+ "\"obj\":{\"properties\":{\"one\":{\"type\":\"long\"}," +
|
|
|
+ "\"runtime\":{\"type\":\"object\",\"dynamic\":\"runtime\"}}}}}}}",
|
|
|
+ Strings.toString(client().admin().indices().prepareGetMappings("test").get()));
|
|
|
+
|
|
|
+ assertAcked(client().admin().indices().preparePutMapping("test").setSource("{\"_doc\":{\"properties\":{\"obj\":{\"properties\":" +
|
|
|
+ "{\"runtime\":{\"properties\":{\"dynamic\":{\"type\":\"object\", \"dynamic\":true}}}}}}}}", XContentType.JSON));
|
|
|
+
|
|
|
+ assertEquals(RestStatus.CREATED, client().prepareIndex("test").setSource("obj.runtime.dynamic.leaf", 1).get().status());
|
|
|
+ GetMappingsResponse getMappingsResponse = client().admin().indices().prepareGetMappings("test").get();
|
|
|
+ Map<String, Object> sourceAsMap = getMappingsResponse.getMappings().get("test").sourceAsMap();
|
|
|
+ assertThat(
|
|
|
+ XContentMapValues.extractRawValues("properties.obj.properties.runtime.properties.dynamic.properties.leaf.type", sourceAsMap),
|
|
|
+ contains("long"));
|
|
|
+ }
|
|
|
+
|
|
|
+ private static Map<String, Object> getMappedField(Map<String, Object> sourceAsMap, String name) {
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
+ Map<String, Object> properties = (Map<String, Object>)sourceAsMap.get("properties");
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
+ Map<String, Object> mappedField = (Map<String, Object>)properties.get(name);
|
|
|
+ return mappedField;
|
|
|
+ }
|
|
|
}
|