Mapper plugin overwrites multifield mapping

If you define some specific mapping for your file content, such as the following:

```javascript
{
    "person": {
        "properties": {
            "file": {
                "type": "attachment",
                "path": "full",
                "fields": {
                    "file": {
                        "type": "multifield",
                        "fields": {
                            "file": { "type": "string" },
                            "suggest": { "type": "string" }
                        }
                    }
                }
            }
        }
    }
}
```

And then, if you ask back the mapping, you get:

```javascript
{
   "person":{
      "properties":{
         "file":{
            "type":"attachment",
            "path":"full",
            "fields":{
               "file":{
                  "type":"string"
               },
               "author":{
                  "type":"string"
               },
               "title":{
                  "type":"string"
               },
               "name":{
                  "type":"string"
               },
               "date":{
                  "type":"date",
                  "format":"dateOptionalTime"
               },
               "keywords":{
                  "type":"string"
               },
               "content_type":{
                  "type":"string"
               }
            }
         }
      }
   }
}
```

All your settings have been overwrited by the mapper plugin.

Closes #37.
This commit is contained in:
David Pilato 2013-08-19 11:01:02 +02:00
parent d2e2fb5cdf
commit d7a2e7e2ff
3 changed files with 186 additions and 38 deletions

View File

@ -27,6 +27,7 @@ import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.mapper.*;
import org.elasticsearch.index.mapper.core.DateFieldMapper;
import org.elasticsearch.index.mapper.core.StringFieldMapper;
import org.elasticsearch.index.mapper.multifield.MultiFieldMapper;
import java.io.IOException;
import java.util.Map;
@ -69,19 +70,19 @@ public class AttachmentMapper implements Mapper {
private Integer defaultIndexedChars = null;
private StringFieldMapper.Builder contentBuilder;
private Mapper.Builder contentBuilder;
private StringFieldMapper.Builder titleBuilder = stringField("title");
private Mapper.Builder titleBuilder = stringField("title");
private StringFieldMapper.Builder nameBuilder = stringField("name");
private Mapper.Builder nameBuilder = stringField("name");
private StringFieldMapper.Builder authorBuilder = stringField("author");
private Mapper.Builder authorBuilder = stringField("author");
private StringFieldMapper.Builder keywordsBuilder = stringField("keywords");
private Mapper.Builder keywordsBuilder = stringField("keywords");
private DateFieldMapper.Builder dateBuilder = dateField("date");
private Mapper.Builder dateBuilder = dateField("date");
private StringFieldMapper.Builder contentTypeBuilder = stringField("content_type");
private Mapper.Builder contentTypeBuilder = stringField("content_type");
public Builder(String name) {
super(name);
@ -99,37 +100,37 @@ public class AttachmentMapper implements Mapper {
return this;
}
public Builder content(StringFieldMapper.Builder content) {
public Builder content(Mapper.Builder content) {
this.contentBuilder = content;
return this;
}
public Builder date(DateFieldMapper.Builder date) {
public Builder date(Mapper.Builder date) {
this.dateBuilder = date;
return this;
}
public Builder author(StringFieldMapper.Builder author) {
public Builder author(Mapper.Builder author) {
this.authorBuilder = author;
return this;
}
public Builder title(StringFieldMapper.Builder title) {
public Builder title(Mapper.Builder title) {
this.titleBuilder = title;
return this;
}
public Builder name(StringFieldMapper.Builder name) {
public Builder name(Mapper.Builder name) {
this.nameBuilder = name;
return this;
}
public Builder keywords(StringFieldMapper.Builder keywords) {
public Builder keywords(Mapper.Builder keywords) {
this.keywordsBuilder = keywords;
return this;
}
public Builder contentType(StringFieldMapper.Builder contentType) {
public Builder contentType(Mapper.Builder contentType) {
this.contentTypeBuilder = contentType;
return this;
}
@ -140,16 +141,16 @@ public class AttachmentMapper implements Mapper {
context.path().pathType(pathType);
// create the content mapper under the actual name
StringFieldMapper contentMapper = contentBuilder.build(context);
Mapper contentMapper = contentBuilder.build(context);
// create the DC one under the name
context.path().add(name);
DateFieldMapper dateMapper = dateBuilder.build(context);
StringFieldMapper authorMapper = authorBuilder.build(context);
StringFieldMapper titleMapper = titleBuilder.build(context);
StringFieldMapper nameMapper = nameBuilder.build(context);
StringFieldMapper keywordsMapper = keywordsBuilder.build(context);
StringFieldMapper contentTypeMapper = contentTypeBuilder.build(context);
Mapper dateMapper = dateBuilder.build(context);
Mapper authorMapper = authorBuilder.build(context);
Mapper titleMapper = titleBuilder.build(context);
Mapper nameMapper = nameBuilder.build(context);
Mapper keywordsMapper = keywordsBuilder.build(context);
Mapper contentTypeMapper = contentTypeBuilder.build(context);
context.path().remove();
context.path().pathType(origPathType);
@ -199,21 +200,30 @@ public class AttachmentMapper implements Mapper {
String propName = entry1.getKey();
Object propNode = entry1.getValue();
// Check if we have a multifield here
boolean isMultifield = false;
if (propNode != null && propNode instanceof Map) {
Object oType = ((Map<String, Object>) propNode).get("type");
if (oType != null && oType.equals(MultiFieldMapper.CONTENT_TYPE)) {
isMultifield = true;
}
}
if (name.equals(propName)) {
// that is the content
builder.content((StringFieldMapper.Builder) parserContext.typeParser("string").parse(name, (Map<String, Object>) propNode, parserContext));
builder.content(parserContext.typeParser(isMultifield? MultiFieldMapper.CONTENT_TYPE:StringFieldMapper.CONTENT_TYPE).parse(name, (Map<String, Object>) propNode, parserContext));
} else if ("date".equals(propName)) {
builder.date((DateFieldMapper.Builder) parserContext.typeParser("date").parse("date", (Map<String, Object>) propNode, parserContext));
builder.date(parserContext.typeParser(isMultifield? MultiFieldMapper.CONTENT_TYPE:DateFieldMapper.CONTENT_TYPE).parse("date", (Map<String, Object>) propNode, parserContext));
} else if ("title".equals(propName)) {
builder.title((StringFieldMapper.Builder) parserContext.typeParser("string").parse("title", (Map<String, Object>) propNode, parserContext));
builder.title(parserContext.typeParser(isMultifield? MultiFieldMapper.CONTENT_TYPE:StringFieldMapper.CONTENT_TYPE).parse("title", (Map<String, Object>) propNode, parserContext));
} else if ("name".equals(propName)) {
builder.name((StringFieldMapper.Builder) parserContext.typeParser("string").parse("name", (Map<String, Object>) propNode, parserContext));
builder.name(parserContext.typeParser(isMultifield? MultiFieldMapper.CONTENT_TYPE:StringFieldMapper.CONTENT_TYPE).parse("name", (Map<String, Object>) propNode, parserContext));
} else if ("author".equals(propName)) {
builder.author((StringFieldMapper.Builder) parserContext.typeParser("string").parse("author", (Map<String, Object>) propNode, parserContext));
builder.author(parserContext.typeParser(isMultifield? MultiFieldMapper.CONTENT_TYPE:StringFieldMapper.CONTENT_TYPE).parse("author", (Map<String, Object>) propNode, parserContext));
} else if ("keywords".equals(propName)) {
builder.keywords((StringFieldMapper.Builder) parserContext.typeParser("string").parse("keywords", (Map<String, Object>) propNode, parserContext));
builder.keywords(parserContext.typeParser(isMultifield? MultiFieldMapper.CONTENT_TYPE:StringFieldMapper.CONTENT_TYPE).parse("keywords", (Map<String, Object>) propNode, parserContext));
} else if ("content_type".equals(propName)) {
builder.contentType((StringFieldMapper.Builder) parserContext.typeParser("string").parse("content_type", (Map<String, Object>) propNode, parserContext));
builder.contentType(parserContext.typeParser(isMultifield? MultiFieldMapper.CONTENT_TYPE:StringFieldMapper.CONTENT_TYPE).parse("content_type", (Map<String, Object>) propNode, parserContext));
}
}
}
@ -229,23 +239,23 @@ public class AttachmentMapper implements Mapper {
private final int defaultIndexedChars;
private final StringFieldMapper contentMapper;
private final Mapper contentMapper;
private final DateFieldMapper dateMapper;
private final Mapper dateMapper;
private final StringFieldMapper authorMapper;
private final Mapper authorMapper;
private final StringFieldMapper titleMapper;
private final Mapper titleMapper;
private final StringFieldMapper nameMapper;
private final Mapper nameMapper;
private final StringFieldMapper keywordsMapper;
private final Mapper keywordsMapper;
private final StringFieldMapper contentTypeMapper;
private final Mapper contentTypeMapper;
public AttachmentMapper(String name, ContentPath.Type pathType, int defaultIndexedChars, StringFieldMapper contentMapper,
DateFieldMapper dateMapper, StringFieldMapper titleMapper, StringFieldMapper nameMapper, StringFieldMapper authorMapper,
StringFieldMapper keywordsMapper, StringFieldMapper contentTypeMapper) {
public AttachmentMapper(String name, ContentPath.Type pathType, int defaultIndexedChars, Mapper contentMapper,
Mapper dateMapper, Mapper titleMapper, Mapper nameMapper, Mapper authorMapper,
Mapper keywordsMapper, Mapper contentTypeMapper) {
this.name = name;
this.pathType = pathType;
this.defaultIndexedChars = defaultIndexedChars;

View File

@ -0,0 +1,77 @@
/*
* Licensed to ElasticSearch and Shay Banon 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.xcontent;
import org.elasticsearch.index.Index;
import org.elasticsearch.index.analysis.AnalysisService;
import org.elasticsearch.index.mapper.DocumentMapper;
import org.elasticsearch.index.mapper.DocumentMapperParser;
import org.elasticsearch.index.mapper.attachment.AttachmentMapper;
import org.elasticsearch.index.mapper.core.DateFieldMapper;
import org.elasticsearch.index.mapper.core.StringFieldMapper;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import static org.elasticsearch.common.io.Streams.copyToStringFromClasspath;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.instanceOf;
/**
*
*/
@Test
public class MultifieldAttachmentMapperTests {
private DocumentMapperParser mapperParser;
@BeforeClass
public void setupMapperParser() {
mapperParser = new DocumentMapperParser(new Index("test"), new AnalysisService(new Index("test")), null, null);
mapperParser.putTypeParser(AttachmentMapper.CONTENT_TYPE, new AttachmentMapper.TypeParser());
}
@Test
public void testSimpleMappings() throws Exception {
String mapping = copyToStringFromClasspath("/org/elasticsearch/index/mapper/multifield/multifield-mapping.json");
DocumentMapper docMapper = mapperParser.parse(mapping);
assertThat(docMapper.mappers().fullName("file").mapper(), instanceOf(StringFieldMapper.class));
assertThat(docMapper.mappers().fullName("file.suggest").mapper(), instanceOf(StringFieldMapper.class));
assertThat(docMapper.mappers().fullName("file.date").mapper(), instanceOf(DateFieldMapper.class));
assertThat(docMapper.mappers().fullName("file.date.string").mapper(), instanceOf(StringFieldMapper.class));
assertThat(docMapper.mappers().fullName("file.title").mapper(), instanceOf(StringFieldMapper.class));
assertThat(docMapper.mappers().fullName("file.title.suggest").mapper(), instanceOf(StringFieldMapper.class));
assertThat(docMapper.mappers().fullName("file.name").mapper(), instanceOf(StringFieldMapper.class));
assertThat(docMapper.mappers().fullName("file.name.suggest").mapper(), instanceOf(StringFieldMapper.class));
assertThat(docMapper.mappers().fullName("file.author").mapper(), instanceOf(StringFieldMapper.class));
assertThat(docMapper.mappers().fullName("file.author.suggest").mapper(), instanceOf(StringFieldMapper.class));
assertThat(docMapper.mappers().fullName("file.keywords").mapper(), instanceOf(StringFieldMapper.class));
assertThat(docMapper.mappers().fullName("file.keywords.suggest").mapper(), instanceOf(StringFieldMapper.class));
assertThat(docMapper.mappers().fullName("file.content_type").mapper(), instanceOf(StringFieldMapper.class));
assertThat(docMapper.mappers().fullName("file.content_type.suggest").mapper(), instanceOf(StringFieldMapper.class));
}
}

View File

@ -0,0 +1,61 @@
{
"person": {
"properties": {
"file": {
"type": "attachment",
"path": "full",
"fields": {
"file": {
"type": "multi_field",
"fields": {
"file": { "type": "string" },
"suggest": { "type": "string" }
}
},
"date": {
"type": "multi_field",
"fields": {
"date": { "type": "date" },
"string": { "type": "string" }
}
},
"title": {
"type": "multi_field",
"fields": {
"title": { "type": "string" },
"suggest": { "type": "string" }
}
},
"name": {
"type": "multi_field",
"fields": {
"name": { "type": "string" },
"suggest": { "type": "string" }
}
},
"author": {
"type": "multi_field",
"fields": {
"author": { "type": "string" },
"suggest": { "type": "string" }
}
},
"keywords": {
"type": "multi_field",
"fields": {
"keywords": { "type": "string" },
"suggest": { "type": "string" }
}
},
"content_type": {
"type": "multi_field",
"fields": {
"content_type": { "type": "string" },
"suggest": { "type": "string" }
}
}
}
}
}
}
}