|
|
@@ -20,13 +20,17 @@
|
|
|
package org.elasticsearch.index.mapper.copyto;
|
|
|
|
|
|
import com.google.common.collect.ImmutableList;
|
|
|
+import org.apache.lucene.index.IndexableField;
|
|
|
import org.elasticsearch.common.bytes.BytesReference;
|
|
|
import org.elasticsearch.common.xcontent.ToXContent;
|
|
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
|
|
+import org.elasticsearch.common.xcontent.XContentFactory;
|
|
|
import org.elasticsearch.common.xcontent.json.JsonXContent;
|
|
|
import org.elasticsearch.index.mapper.*;
|
|
|
+import org.elasticsearch.index.mapper.ParseContext.Document;
|
|
|
import org.elasticsearch.index.mapper.core.LongFieldMapper;
|
|
|
import org.elasticsearch.index.mapper.core.StringFieldMapper;
|
|
|
+import org.elasticsearch.index.service.IndexService;
|
|
|
import org.elasticsearch.test.ElasticsearchSingleNodeTest;
|
|
|
import org.junit.Test;
|
|
|
|
|
|
@@ -223,4 +227,105 @@ public class CopyToMapperTests extends ElasticsearchSingleNodeTest {
|
|
|
assertThat(fields.get(1), equalTo("bar"));
|
|
|
}
|
|
|
|
|
|
+ public void testCopyToNestedField() throws Exception {
|
|
|
+ IndexService indexService = createIndex("test");
|
|
|
+ DocumentMapperParser parser = indexService.mapperService().documentMapperParser();
|
|
|
+ for (boolean mapped : new boolean[] {true, false}) {
|
|
|
+ XContentBuilder mapping = jsonBuilder().startObject()
|
|
|
+ .startObject("type")
|
|
|
+ .startObject("properties")
|
|
|
+ .startObject("n1")
|
|
|
+ .field("type", "nested")
|
|
|
+ .startObject("properties")
|
|
|
+ .startObject("n2")
|
|
|
+ .field("type", "nested")
|
|
|
+ .startObject("properties")
|
|
|
+ .startObject("source")
|
|
|
+ .field("type", "long")
|
|
|
+ .startArray("copy_to")
|
|
|
+ .value("target") // should go to the root doc
|
|
|
+ .value("n1.target") // should go to the parent doc
|
|
|
+ .value("n1.n2.target") // should go to the current doc
|
|
|
+ .endArray()
|
|
|
+ .endObject();
|
|
|
+ for (int i = 0; i < 3; ++i) {
|
|
|
+ if (mapped) {
|
|
|
+ mapping = mapping.startObject("target").field("type", "long").endObject();
|
|
|
+ }
|
|
|
+ mapping = mapping.endObject().endObject();
|
|
|
+ }
|
|
|
+ mapping = mapping.endObject();
|
|
|
+
|
|
|
+ DocumentMapper mapper = parser.parse(mapping.string());
|
|
|
+
|
|
|
+ XContentBuilder jsonDoc = XContentFactory.jsonBuilder()
|
|
|
+ .startObject()
|
|
|
+ .startArray("n1")
|
|
|
+ .startObject()
|
|
|
+ .startArray("n2")
|
|
|
+ .startObject()
|
|
|
+ .field("source", 3)
|
|
|
+ .endObject()
|
|
|
+ .startObject()
|
|
|
+ .field("source", 5)
|
|
|
+ .endObject()
|
|
|
+ .endArray()
|
|
|
+ .endObject()
|
|
|
+ .startObject()
|
|
|
+ .startArray("n2")
|
|
|
+ .startObject()
|
|
|
+ .field("source", 7)
|
|
|
+ .endObject()
|
|
|
+ .endArray()
|
|
|
+ .endObject()
|
|
|
+ .endArray()
|
|
|
+ .endObject();
|
|
|
+
|
|
|
+ ParsedDocument doc = mapper.parse("type", "1", jsonDoc.bytes());
|
|
|
+ assertEquals(6, doc.docs().size());
|
|
|
+
|
|
|
+ Document nested = doc.docs().get(0);
|
|
|
+ assertFieldValue(nested, "n1.n2.target", 7L);
|
|
|
+ assertFieldValue(nested, "n1.target");
|
|
|
+ assertFieldValue(nested, "target");
|
|
|
+
|
|
|
+ nested = doc.docs().get(2);
|
|
|
+ assertFieldValue(nested, "n1.n2.target", 5L);
|
|
|
+ assertFieldValue(nested, "n1.target");
|
|
|
+ assertFieldValue(nested, "target");
|
|
|
+
|
|
|
+ nested = doc.docs().get(3);
|
|
|
+ assertFieldValue(nested, "n1.n2.target", 3L);
|
|
|
+ assertFieldValue(nested, "n1.target");
|
|
|
+ assertFieldValue(nested, "target");
|
|
|
+
|
|
|
+ Document parent = doc.docs().get(1);
|
|
|
+ assertFieldValue(parent, "target");
|
|
|
+ assertFieldValue(parent, "n1.target", 7L);
|
|
|
+ assertFieldValue(parent, "n1.n2.target");
|
|
|
+
|
|
|
+ parent = doc.docs().get(4);
|
|
|
+ assertFieldValue(parent, "target");
|
|
|
+ assertFieldValue(parent, "n1.target", 3L, 5L);
|
|
|
+ assertFieldValue(parent, "n1.n2.target");
|
|
|
+
|
|
|
+ Document root = doc.docs().get(5);
|
|
|
+ assertFieldValue(root, "target", 3L, 5L, 7L);
|
|
|
+ assertFieldValue(root, "n1.target");
|
|
|
+ assertFieldValue(root, "n1.n2.target");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void assertFieldValue(Document doc, String field, Number... expected) {
|
|
|
+ IndexableField[] values = doc.getFields(field);
|
|
|
+ if (values == null) {
|
|
|
+ values = new IndexableField[0];
|
|
|
+ }
|
|
|
+ Number[] actual = new Number[values.length];
|
|
|
+ for (int i = 0; i < values.length; ++i) {
|
|
|
+ actual[i] = values[i].numericValue();
|
|
|
+ }
|
|
|
+ assertArrayEquals(expected, actual);
|
|
|
+ }
|
|
|
+
|
|
|
}
|