diff --git a/core/src/main/java/org/elasticsearch/index/mapper/DocumentParser.java b/core/src/main/java/org/elasticsearch/index/mapper/DocumentParser.java index a314a0ef37659..93fecfba6fd24 100644 --- a/core/src/main/java/org/elasticsearch/index/mapper/DocumentParser.java +++ b/core/src/main/java/org/elasticsearch/index/mapper/DocumentParser.java @@ -312,9 +312,6 @@ private static Mapper parseObjectOrField(ParseContext context, Mapper mapper) th } else { FieldMapper fieldMapper = (FieldMapper)mapper; Mapper update = fieldMapper.parse(context); - if (fieldMapper.copyTo() != null) { - parseCopyFields(context, fieldMapper, fieldMapper.copyTo().copyToFields()); - } return update; } } @@ -683,7 +680,7 @@ private static ObjectMapper parseDynamicValue(final ParseContext context, Object } /** Creates instances of the fields that the current field should be copied to */ - private static void parseCopyFields(ParseContext context, FieldMapper fieldMapper, List copyToFields) throws IOException { + public static void parseCopyFields(ParseContext context, FieldMapper fieldMapper, List copyToFields) throws IOException { if (!context.isWithinCopyTo() && copyToFields.isEmpty() == false) { context = context.createCopyToContext(); for (String field : copyToFields) { diff --git a/core/src/main/java/org/elasticsearch/index/mapper/FieldMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/FieldMapper.java index 1e43ad9e32649..3dd4752ab2f85 100644 --- a/core/src/main/java/org/elasticsearch/index/mapper/FieldMapper.java +++ b/core/src/main/java/org/elasticsearch/index/mapper/FieldMapper.java @@ -339,6 +339,9 @@ public Mapper parse(ParseContext context) throws IOException { throw new MapperParsingException("failed to parse [" + fieldType().names().fullName() + "]", e); } multiFields.parse(this, context); + if (copyTo() != null) { + DocumentParser.parseCopyFields(context, this, this.copyTo().copyToFields()); + } return null; } diff --git a/core/src/test/java/org/elasticsearch/index/mapper/copyto/CopyToMapperIntegrationIT.java b/core/src/test/java/org/elasticsearch/index/mapper/copyto/CopyToMapperIntegrationIT.java index 5919c52bc31db..3e38182a3e881 100644 --- a/core/src/test/java/org/elasticsearch/index/mapper/copyto/CopyToMapperIntegrationIT.java +++ b/core/src/test/java/org/elasticsearch/index/mapper/copyto/CopyToMapperIntegrationIT.java @@ -31,7 +31,9 @@ import java.io.IOException; +import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked; +import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSearchResponse; import static org.hamcrest.Matchers.equalTo; /** @@ -92,4 +94,26 @@ private XContentBuilder createDynamicTemplateMapping() throws IOException { .endArray(); } + public void testCopyToWithinMultiField() throws IOException { + String mapping = jsonBuilder().startObject().startObject("type").startObject("properties") + .startObject("copy_test") + .field("type", "string") + .startObject("fields") + .startObject("raw") + .field("type", "string") + .field("copy_to", "another_field") + .endObject() + .endObject() + .endObject() + .endObject().endObject().endObject().string(); + assertAcked( + client().admin().indices().prepareCreate("test-idx") + .addMapping("type", mapping) + ); + client().prepareIndex("test-idx", "type").setSource("{\"copy_test\":\"foo bar\"}").get(); + refresh(); + SearchResponse searchResponse = client().prepareSearch().setQuery(QueryBuilders.termQuery("another_field", "foo")).get(); + assertSearchResponse(searchResponse); + assertThat(searchResponse.getHits().getHits().length, equalTo(1)); + } } diff --git a/core/src/test/java/org/elasticsearch/index/mapper/copyto/CopyToMapperTests.java b/core/src/test/java/org/elasticsearch/index/mapper/copyto/CopyToMapperTests.java index 419dde456de13..694aa17daad3a 100644 --- a/core/src/test/java/org/elasticsearch/index/mapper/copyto/CopyToMapperTests.java +++ b/core/src/test/java/org/elasticsearch/index/mapper/copyto/CopyToMapperTests.java @@ -20,6 +20,7 @@ package org.elasticsearch.index.mapper.copyto; import org.apache.lucene.index.IndexableField; +import org.elasticsearch.common.bytes.BytesArray; import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContentBuilder; @@ -40,6 +41,7 @@ import org.elasticsearch.test.ESSingleNodeTestCase; import org.junit.Test; +import java.nio.charset.Charset; import java.util.Arrays; import java.util.List; import java.util.Map; @@ -358,4 +360,21 @@ private void assertFieldValue(Document doc, String field, Number... expected) { assertArrayEquals(expected, actual); } + @Test + public void testCopyToInMultiFields() throws Exception { + String mapping = jsonBuilder().startObject().startObject("type").startObject("properties") + .startObject("copy_test") + .field("type", "string") + .startObject("fields") + .startObject("raw") + .field("type", "string") + .field("copy_to", "another_field") + .endObject() + .endObject() + .endObject() + .endObject().endObject().endObject().string(); + DocumentMapper docMapper = createIndex("test").mapperService().documentMapperParser().parse(mapping); + ParsedDocument doc = docMapper.parse("test", "type", "1", new BytesArray("{\"copy_test\":\"foo bar\"}")); + assertThat(doc.docs().get(0).getFields("another_field")[0].stringValue(), equalTo("foo bar")); + } }