Skip to content

Commit d7a2e7e

Browse files
committed
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 elastic#37.
1 parent d2e2fb5 commit d7a2e7e

File tree

3 files changed

+186
-38
lines changed

3 files changed

+186
-38
lines changed

src/main/java/org/elasticsearch/index/mapper/attachment/AttachmentMapper.java

Lines changed: 48 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import org.elasticsearch.index.mapper.*;
2828
import org.elasticsearch.index.mapper.core.DateFieldMapper;
2929
import org.elasticsearch.index.mapper.core.StringFieldMapper;
30+
import org.elasticsearch.index.mapper.multifield.MultiFieldMapper;
3031

3132
import java.io.IOException;
3233
import java.util.Map;
@@ -69,19 +70,19 @@ public static class Builder extends Mapper.Builder<Builder, AttachmentMapper> {
6970

7071
private Integer defaultIndexedChars = null;
7172

72-
private StringFieldMapper.Builder contentBuilder;
73+
private Mapper.Builder contentBuilder;
7374

74-
private StringFieldMapper.Builder titleBuilder = stringField("title");
75+
private Mapper.Builder titleBuilder = stringField("title");
7576

76-
private StringFieldMapper.Builder nameBuilder = stringField("name");
77+
private Mapper.Builder nameBuilder = stringField("name");
7778

78-
private StringFieldMapper.Builder authorBuilder = stringField("author");
79+
private Mapper.Builder authorBuilder = stringField("author");
7980

80-
private StringFieldMapper.Builder keywordsBuilder = stringField("keywords");
81+
private Mapper.Builder keywordsBuilder = stringField("keywords");
8182

82-
private DateFieldMapper.Builder dateBuilder = dateField("date");
83+
private Mapper.Builder dateBuilder = dateField("date");
8384

84-
private StringFieldMapper.Builder contentTypeBuilder = stringField("content_type");
85+
private Mapper.Builder contentTypeBuilder = stringField("content_type");
8586

8687
public Builder(String name) {
8788
super(name);
@@ -99,37 +100,37 @@ public Builder defaultIndexedChars(int defaultIndexedChars) {
99100
return this;
100101
}
101102

102-
public Builder content(StringFieldMapper.Builder content) {
103+
public Builder content(Mapper.Builder content) {
103104
this.contentBuilder = content;
104105
return this;
105106
}
106107

107-
public Builder date(DateFieldMapper.Builder date) {
108+
public Builder date(Mapper.Builder date) {
108109
this.dateBuilder = date;
109110
return this;
110111
}
111112

112-
public Builder author(StringFieldMapper.Builder author) {
113+
public Builder author(Mapper.Builder author) {
113114
this.authorBuilder = author;
114115
return this;
115116
}
116117

117-
public Builder title(StringFieldMapper.Builder title) {
118+
public Builder title(Mapper.Builder title) {
118119
this.titleBuilder = title;
119120
return this;
120121
}
121122

122-
public Builder name(StringFieldMapper.Builder name) {
123+
public Builder name(Mapper.Builder name) {
123124
this.nameBuilder = name;
124125
return this;
125126
}
126127

127-
public Builder keywords(StringFieldMapper.Builder keywords) {
128+
public Builder keywords(Mapper.Builder keywords) {
128129
this.keywordsBuilder = keywords;
129130
return this;
130131
}
131132

132-
public Builder contentType(StringFieldMapper.Builder contentType) {
133+
public Builder contentType(Mapper.Builder contentType) {
133134
this.contentTypeBuilder = contentType;
134135
return this;
135136
}
@@ -140,16 +141,16 @@ public AttachmentMapper build(BuilderContext context) {
140141
context.path().pathType(pathType);
141142

142143
// create the content mapper under the actual name
143-
StringFieldMapper contentMapper = contentBuilder.build(context);
144+
Mapper contentMapper = contentBuilder.build(context);
144145

145146
// create the DC one under the name
146147
context.path().add(name);
147-
DateFieldMapper dateMapper = dateBuilder.build(context);
148-
StringFieldMapper authorMapper = authorBuilder.build(context);
149-
StringFieldMapper titleMapper = titleBuilder.build(context);
150-
StringFieldMapper nameMapper = nameBuilder.build(context);
151-
StringFieldMapper keywordsMapper = keywordsBuilder.build(context);
152-
StringFieldMapper contentTypeMapper = contentTypeBuilder.build(context);
148+
Mapper dateMapper = dateBuilder.build(context);
149+
Mapper authorMapper = authorBuilder.build(context);
150+
Mapper titleMapper = titleBuilder.build(context);
151+
Mapper nameMapper = nameBuilder.build(context);
152+
Mapper keywordsMapper = keywordsBuilder.build(context);
153+
Mapper contentTypeMapper = contentTypeBuilder.build(context);
153154
context.path().remove();
154155

155156
context.path().pathType(origPathType);
@@ -199,21 +200,30 @@ public Mapper.Builder parse(String name, Map<String, Object> node, ParserContext
199200
String propName = entry1.getKey();
200201
Object propNode = entry1.getValue();
201202

203+
// Check if we have a multifield here
204+
boolean isMultifield = false;
205+
if (propNode != null && propNode instanceof Map) {
206+
Object oType = ((Map<String, Object>) propNode).get("type");
207+
if (oType != null && oType.equals(MultiFieldMapper.CONTENT_TYPE)) {
208+
isMultifield = true;
209+
}
210+
}
211+
202212
if (name.equals(propName)) {
203213
// that is the content
204-
builder.content((StringFieldMapper.Builder) parserContext.typeParser("string").parse(name, (Map<String, Object>) propNode, parserContext));
214+
builder.content(parserContext.typeParser(isMultifield? MultiFieldMapper.CONTENT_TYPE:StringFieldMapper.CONTENT_TYPE).parse(name, (Map<String, Object>) propNode, parserContext));
205215
} else if ("date".equals(propName)) {
206-
builder.date((DateFieldMapper.Builder) parserContext.typeParser("date").parse("date", (Map<String, Object>) propNode, parserContext));
216+
builder.date(parserContext.typeParser(isMultifield? MultiFieldMapper.CONTENT_TYPE:DateFieldMapper.CONTENT_TYPE).parse("date", (Map<String, Object>) propNode, parserContext));
207217
} else if ("title".equals(propName)) {
208-
builder.title((StringFieldMapper.Builder) parserContext.typeParser("string").parse("title", (Map<String, Object>) propNode, parserContext));
218+
builder.title(parserContext.typeParser(isMultifield? MultiFieldMapper.CONTENT_TYPE:StringFieldMapper.CONTENT_TYPE).parse("title", (Map<String, Object>) propNode, parserContext));
209219
} else if ("name".equals(propName)) {
210-
builder.name((StringFieldMapper.Builder) parserContext.typeParser("string").parse("name", (Map<String, Object>) propNode, parserContext));
220+
builder.name(parserContext.typeParser(isMultifield? MultiFieldMapper.CONTENT_TYPE:StringFieldMapper.CONTENT_TYPE).parse("name", (Map<String, Object>) propNode, parserContext));
211221
} else if ("author".equals(propName)) {
212-
builder.author((StringFieldMapper.Builder) parserContext.typeParser("string").parse("author", (Map<String, Object>) propNode, parserContext));
222+
builder.author(parserContext.typeParser(isMultifield? MultiFieldMapper.CONTENT_TYPE:StringFieldMapper.CONTENT_TYPE).parse("author", (Map<String, Object>) propNode, parserContext));
213223
} else if ("keywords".equals(propName)) {
214-
builder.keywords((StringFieldMapper.Builder) parserContext.typeParser("string").parse("keywords", (Map<String, Object>) propNode, parserContext));
224+
builder.keywords(parserContext.typeParser(isMultifield? MultiFieldMapper.CONTENT_TYPE:StringFieldMapper.CONTENT_TYPE).parse("keywords", (Map<String, Object>) propNode, parserContext));
215225
} else if ("content_type".equals(propName)) {
216-
builder.contentType((StringFieldMapper.Builder) parserContext.typeParser("string").parse("content_type", (Map<String, Object>) propNode, parserContext));
226+
builder.contentType(parserContext.typeParser(isMultifield? MultiFieldMapper.CONTENT_TYPE:StringFieldMapper.CONTENT_TYPE).parse("content_type", (Map<String, Object>) propNode, parserContext));
217227
}
218228
}
219229
}
@@ -229,23 +239,23 @@ public Mapper.Builder parse(String name, Map<String, Object> node, ParserContext
229239

230240
private final int defaultIndexedChars;
231241

232-
private final StringFieldMapper contentMapper;
242+
private final Mapper contentMapper;
233243

234-
private final DateFieldMapper dateMapper;
244+
private final Mapper dateMapper;
235245

236-
private final StringFieldMapper authorMapper;
246+
private final Mapper authorMapper;
237247

238-
private final StringFieldMapper titleMapper;
248+
private final Mapper titleMapper;
239249

240-
private final StringFieldMapper nameMapper;
250+
private final Mapper nameMapper;
241251

242-
private final StringFieldMapper keywordsMapper;
252+
private final Mapper keywordsMapper;
243253

244-
private final StringFieldMapper contentTypeMapper;
254+
private final Mapper contentTypeMapper;
245255

246-
public AttachmentMapper(String name, ContentPath.Type pathType, int defaultIndexedChars, StringFieldMapper contentMapper,
247-
DateFieldMapper dateMapper, StringFieldMapper titleMapper, StringFieldMapper nameMapper, StringFieldMapper authorMapper,
248-
StringFieldMapper keywordsMapper, StringFieldMapper contentTypeMapper) {
256+
public AttachmentMapper(String name, ContentPath.Type pathType, int defaultIndexedChars, Mapper contentMapper,
257+
Mapper dateMapper, Mapper titleMapper, Mapper nameMapper, Mapper authorMapper,
258+
Mapper keywordsMapper, Mapper contentTypeMapper) {
249259
this.name = name;
250260
this.pathType = pathType;
251261
this.defaultIndexedChars = defaultIndexedChars;
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/*
2+
* Licensed to ElasticSearch and Shay Banon under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. ElasticSearch licenses this
6+
* file to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.elasticsearch.index.mapper.xcontent;
21+
22+
import org.elasticsearch.index.Index;
23+
import org.elasticsearch.index.analysis.AnalysisService;
24+
import org.elasticsearch.index.mapper.DocumentMapper;
25+
import org.elasticsearch.index.mapper.DocumentMapperParser;
26+
import org.elasticsearch.index.mapper.attachment.AttachmentMapper;
27+
import org.elasticsearch.index.mapper.core.DateFieldMapper;
28+
import org.elasticsearch.index.mapper.core.StringFieldMapper;
29+
import org.testng.annotations.BeforeClass;
30+
import org.testng.annotations.Test;
31+
32+
import static org.elasticsearch.common.io.Streams.copyToStringFromClasspath;
33+
import static org.hamcrest.MatcherAssert.assertThat;
34+
import static org.hamcrest.Matchers.instanceOf;
35+
36+
/**
37+
*
38+
*/
39+
@Test
40+
public class MultifieldAttachmentMapperTests {
41+
42+
private DocumentMapperParser mapperParser;
43+
44+
@BeforeClass
45+
public void setupMapperParser() {
46+
mapperParser = new DocumentMapperParser(new Index("test"), new AnalysisService(new Index("test")), null, null);
47+
mapperParser.putTypeParser(AttachmentMapper.CONTENT_TYPE, new AttachmentMapper.TypeParser());
48+
}
49+
50+
@Test
51+
public void testSimpleMappings() throws Exception {
52+
String mapping = copyToStringFromClasspath("/org/elasticsearch/index/mapper/multifield/multifield-mapping.json");
53+
DocumentMapper docMapper = mapperParser.parse(mapping);
54+
55+
56+
assertThat(docMapper.mappers().fullName("file").mapper(), instanceOf(StringFieldMapper.class));
57+
assertThat(docMapper.mappers().fullName("file.suggest").mapper(), instanceOf(StringFieldMapper.class));
58+
59+
assertThat(docMapper.mappers().fullName("file.date").mapper(), instanceOf(DateFieldMapper.class));
60+
assertThat(docMapper.mappers().fullName("file.date.string").mapper(), instanceOf(StringFieldMapper.class));
61+
62+
assertThat(docMapper.mappers().fullName("file.title").mapper(), instanceOf(StringFieldMapper.class));
63+
assertThat(docMapper.mappers().fullName("file.title.suggest").mapper(), instanceOf(StringFieldMapper.class));
64+
65+
assertThat(docMapper.mappers().fullName("file.name").mapper(), instanceOf(StringFieldMapper.class));
66+
assertThat(docMapper.mappers().fullName("file.name.suggest").mapper(), instanceOf(StringFieldMapper.class));
67+
68+
assertThat(docMapper.mappers().fullName("file.author").mapper(), instanceOf(StringFieldMapper.class));
69+
assertThat(docMapper.mappers().fullName("file.author.suggest").mapper(), instanceOf(StringFieldMapper.class));
70+
71+
assertThat(docMapper.mappers().fullName("file.keywords").mapper(), instanceOf(StringFieldMapper.class));
72+
assertThat(docMapper.mappers().fullName("file.keywords.suggest").mapper(), instanceOf(StringFieldMapper.class));
73+
74+
assertThat(docMapper.mappers().fullName("file.content_type").mapper(), instanceOf(StringFieldMapper.class));
75+
assertThat(docMapper.mappers().fullName("file.content_type.suggest").mapper(), instanceOf(StringFieldMapper.class));
76+
}
77+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
{
2+
"person": {
3+
"properties": {
4+
"file": {
5+
"type": "attachment",
6+
"path": "full",
7+
"fields": {
8+
"file": {
9+
"type": "multi_field",
10+
"fields": {
11+
"file": { "type": "string" },
12+
"suggest": { "type": "string" }
13+
}
14+
},
15+
"date": {
16+
"type": "multi_field",
17+
"fields": {
18+
"date": { "type": "date" },
19+
"string": { "type": "string" }
20+
}
21+
},
22+
"title": {
23+
"type": "multi_field",
24+
"fields": {
25+
"title": { "type": "string" },
26+
"suggest": { "type": "string" }
27+
}
28+
},
29+
"name": {
30+
"type": "multi_field",
31+
"fields": {
32+
"name": { "type": "string" },
33+
"suggest": { "type": "string" }
34+
}
35+
},
36+
"author": {
37+
"type": "multi_field",
38+
"fields": {
39+
"author": { "type": "string" },
40+
"suggest": { "type": "string" }
41+
}
42+
},
43+
"keywords": {
44+
"type": "multi_field",
45+
"fields": {
46+
"keywords": { "type": "string" },
47+
"suggest": { "type": "string" }
48+
}
49+
},
50+
"content_type": {
51+
"type": "multi_field",
52+
"fields": {
53+
"content_type": { "type": "string" },
54+
"suggest": { "type": "string" }
55+
}
56+
}
57+
}
58+
}
59+
}
60+
}
61+
}

0 commit comments

Comments
 (0)