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:
parent
d2e2fb5cdf
commit
d7a2e7e2ff
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
|
@ -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" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue