better handling of dynamic types in template mappings

This commit is contained in:
kimchy 2010-10-04 12:37:56 +02:00
parent c4d17860a1
commit c737b36df7
6 changed files with 105 additions and 23 deletions

View File

@ -80,7 +80,7 @@ public class XContentDynamicTemplate {
this.mapping = mapping;
}
public boolean match(String name, String suggestedMappingType) {
public boolean match(String name, String dynamicType) {
if (!patternMatch(match, name)) {
return false;
}
@ -88,18 +88,22 @@ public class XContentDynamicTemplate {
return false;
}
if (matchMappingType != null) {
if (suggestedMappingType == null) {
if (dynamicType == null) {
return false;
}
if (!patternMatch(matchMappingType, suggestedMappingType)) {
if (!patternMatch(matchMappingType, dynamicType)) {
return false;
}
}
return true;
}
public String mappingType() {
return mapping.containsKey("type") ? mapping.get("type").toString() : "object";
public boolean hasType() {
return mapping.containsKey("type");
}
public String mappingType(String dynamicType) {
return mapping.containsKey("type") ? mapping.get("type").toString() : dynamicType;
}
private boolean patternMatch(String pattern, String str) {
@ -109,36 +113,36 @@ public class XContentDynamicTemplate {
return str.matches(pattern);
}
public Map<String, Object> mappingForName(String name) {
return processMap(mapping, name);
public Map<String, Object> mappingForName(String name, String dynamicType) {
return processMap(mapping, name, dynamicType);
}
private Map<String, Object> processMap(Map<String, Object> map, String name) {
private Map<String, Object> processMap(Map<String, Object> map, String name, String dynamicType) {
Map<String, Object> processedMap = Maps.newHashMap();
for (Map.Entry<String, Object> entry : map.entrySet()) {
String key = entry.getKey().replace("{name}", name);
String key = entry.getKey().replace("{name}", name).replace("{dynamic_type}", dynamicType).replace("{dynamicType}", dynamicType);
Object value = entry.getValue();
if (value instanceof Map) {
value = processMap((Map<String, Object>) value, name);
value = processMap((Map<String, Object>) value, name, dynamicType);
} else if (value instanceof List) {
value = processList((List) value, name);
value = processList((List) value, name, dynamicType);
} else if (value instanceof String) {
value = value.toString().replace("{name}", name);
value = value.toString().replace("{name}", name).replace("{dynamic_type}", dynamicType).replace("{dynamicType}", dynamicType);
}
processedMap.put(key, value);
}
return processedMap;
}
private List processList(List list, String name) {
private List processList(List list, String name, String dynamicType) {
List processedList = new ArrayList();
for (Object value : list) {
if (value instanceof Map) {
value = processMap((Map<String, Object>) value, name);
value = processMap((Map<String, Object>) value, name, dynamicType);
} else if (value instanceof List) {
value = processList((List) value, name);
value = processList((List) value, name, dynamicType);
} else if (value instanceof String) {
value = value.toString().replace("{name}", name);
value = value.toString().replace("{name}", name).replace("{dynamic_type}", dynamicType).replace("{dynamicType}", dynamicType);
}
processedList.add(value);
}

View File

@ -553,18 +553,18 @@ public class XContentObjectMapper implements XContentMapper, XContentIncludeInAl
}
}
private XContentMapper.Builder findTemplateBuilder(ParseContext context, String name, String mappingType) {
XContentDynamicTemplate dynamicTemplate = findTemplate(name, mappingType);
private XContentMapper.Builder findTemplateBuilder(ParseContext context, String name, String dynamicType) {
XContentDynamicTemplate dynamicTemplate = findTemplate(name, dynamicType);
if (dynamicTemplate == null) {
return null;
}
XContentTypeParser.ParserContext parserContext = context.docMapperParser().parserContext();
return parserContext.typeParser(dynamicTemplate.mappingType()).parse(name, dynamicTemplate.mappingForName(name), parserContext);
return parserContext.typeParser(dynamicTemplate.mappingType(dynamicType)).parse(name, dynamicTemplate.mappingForName(name, dynamicType), parserContext);
}
private XContentDynamicTemplate findTemplate(String name, String mappingType) {
private XContentDynamicTemplate findTemplate(String name, String dynamicType) {
for (XContentDynamicTemplate dynamicTemplate : dynamicTemplates) {
if (dynamicTemplate.match(name, mappingType)) {
if (dynamicTemplate.match(name, dynamicType)) {
return dynamicTemplate;
}
}

View File

@ -0,0 +1,61 @@
/*
* Licensed to Elastic Search and Shay Banon under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. Elastic Search 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.dynamictemplate.genericstore;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.elasticsearch.index.mapper.FieldMappers;
import org.elasticsearch.index.mapper.xcontent.XContentDocumentMapper;
import org.elasticsearch.index.mapper.xcontent.XContentMapperTests;
import org.testng.annotations.Test;
import static org.elasticsearch.common.io.Streams.*;
import static org.hamcrest.MatcherAssert.*;
import static org.hamcrest.Matchers.*;
/**
* @author kimchy (shay.banon)
*/
public class GenericStoreDynamicTempalteTests {
@Test public void testSimple() throws Exception {
String mapping = copyToStringFromClasspath("/org/elasticsearch/index/mapper/xcontent/dynamictemplate/genericstore/test-mapping.json");
XContentDocumentMapper docMapper = XContentMapperTests.newParser().parse(mapping);
byte[] json = copyToBytesFromClasspath("/org/elasticsearch/index/mapper/xcontent/dynamictemplate/genericstore/test-data.json");
Document doc = docMapper.parse(json).doc();
Field f = doc.getField("name");
assertThat(f.name(), equalTo("name"));
assertThat(f.stringValue(), equalTo("some name"));
assertThat(f.isStored(), equalTo(true));
FieldMappers fieldMappers = docMapper.mappers().fullName("name");
assertThat(fieldMappers.mappers().size(), equalTo(1));
assertThat(fieldMappers.mapper().stored(), equalTo(true));
f = doc.getField("age");
assertThat(f.name(), equalTo("age"));
assertThat(f.isStored(), equalTo(true));
fieldMappers = docMapper.mappers().fullName("age");
assertThat(fieldMappers.mappers().size(), equalTo(1));
assertThat(fieldMappers.mapper().stored(), equalTo(true));
}
}

View File

@ -0,0 +1,5 @@
{
"_id" : "1",
"name" : "some name",
"age" : 1
}

View File

@ -0,0 +1,12 @@
{
"person" : {
"dynamic_templates" : [
{
"match" : "*",
"mapping" : {
"store" : "yes"
}
}
]
}
}

View File

@ -6,8 +6,8 @@
"mapping" : {
"type" : "multi_field",
"fields" : {
"{name}" : {"type": "string", "index" : "analyzed", "store" : "yes"},
"org" : {"type": "string", "index" : "not_analyzed", "store" : "yes"}
"{name}" : {"type": "{dynamic_type}", "index" : "analyzed", "store" : "yes"},
"org" : {"type": "{dynamic_type}", "index" : "not_analyzed", "store" : "yes"}
}
}
},