move dynamic tempaltes to only allow to be defined on root object mapping (so easily reusable and simpler merging) #397.
This commit is contained in:
parent
1578da404c
commit
ad01f19db8
|
@ -22,7 +22,6 @@ package org.elasticsearch.index.mapper.xcontent;
|
||||||
import org.elasticsearch.ElasticSearchIllegalStateException;
|
import org.elasticsearch.ElasticSearchIllegalStateException;
|
||||||
import org.elasticsearch.common.Strings;
|
import org.elasticsearch.common.Strings;
|
||||||
import org.elasticsearch.common.collect.ImmutableMap;
|
import org.elasticsearch.common.collect.ImmutableMap;
|
||||||
import org.elasticsearch.common.collect.Lists;
|
|
||||||
import org.elasticsearch.common.joda.FormatDateTimeFormatter;
|
import org.elasticsearch.common.joda.FormatDateTimeFormatter;
|
||||||
import org.elasticsearch.common.joda.Joda;
|
import org.elasticsearch.common.joda.Joda;
|
||||||
import org.elasticsearch.common.util.concurrent.ThreadSafe;
|
import org.elasticsearch.common.util.concurrent.ThreadSafe;
|
||||||
|
@ -31,7 +30,6 @@ import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
import org.elasticsearch.index.mapper.*;
|
import org.elasticsearch.index.mapper.*;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -62,87 +60,73 @@ public class ObjectMapper implements XContentMapper, IncludeInAllMapper {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Builder extends XContentMapper.Builder<Builder, ObjectMapper> {
|
public static class Builder<T extends Builder, Y extends ObjectMapper> extends XContentMapper.Builder<T, Y> {
|
||||||
|
|
||||||
private boolean enabled = Defaults.ENABLED;
|
protected boolean enabled = Defaults.ENABLED;
|
||||||
|
|
||||||
private boolean dynamic = Defaults.DYNAMIC;
|
protected boolean dynamic = Defaults.DYNAMIC;
|
||||||
|
|
||||||
private ContentPath.Type pathType = Defaults.PATH_TYPE;
|
protected ContentPath.Type pathType = Defaults.PATH_TYPE;
|
||||||
|
|
||||||
private List<FormatDateTimeFormatter> dateTimeFormatters = newArrayList();
|
protected List<FormatDateTimeFormatter> dateTimeFormatters = newArrayList();
|
||||||
|
|
||||||
private Boolean includeInAll;
|
protected Boolean includeInAll;
|
||||||
|
|
||||||
private final List<XContentMapper.Builder> mappersBuilders = newArrayList();
|
protected final List<XContentMapper.Builder> mappersBuilders = newArrayList();
|
||||||
|
|
||||||
private final List<DynamicTemplate> dynamicTemplates = newArrayList();
|
|
||||||
|
|
||||||
public Builder(String name) {
|
public Builder(String name) {
|
||||||
super(name);
|
super(name);
|
||||||
this.builder = this;
|
this.builder = (T) this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder enabled(boolean enabled) {
|
public T enabled(boolean enabled) {
|
||||||
this.enabled = enabled;
|
this.enabled = enabled;
|
||||||
return this;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder dynamic(boolean dynamic) {
|
public T dynamic(boolean dynamic) {
|
||||||
this.dynamic = dynamic;
|
this.dynamic = dynamic;
|
||||||
return this;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder pathType(ContentPath.Type pathType) {
|
public T pathType(ContentPath.Type pathType) {
|
||||||
this.pathType = pathType;
|
this.pathType = pathType;
|
||||||
return this;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder noDateTimeFormatter() {
|
public T noDateTimeFormatter() {
|
||||||
this.dateTimeFormatters = null;
|
this.dateTimeFormatters = null;
|
||||||
return this;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder includeInAll(boolean includeInAll) {
|
public T includeInAll(boolean includeInAll) {
|
||||||
this.includeInAll = includeInAll;
|
this.includeInAll = includeInAll;
|
||||||
return this;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder dateTimeFormatter(Iterable<FormatDateTimeFormatter> dateTimeFormatters) {
|
public T dateTimeFormatter(Iterable<FormatDateTimeFormatter> dateTimeFormatters) {
|
||||||
for (FormatDateTimeFormatter dateTimeFormatter : dateTimeFormatters) {
|
for (FormatDateTimeFormatter dateTimeFormatter : dateTimeFormatters) {
|
||||||
this.dateTimeFormatters.add(dateTimeFormatter);
|
this.dateTimeFormatters.add(dateTimeFormatter);
|
||||||
}
|
}
|
||||||
return this;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder dateTimeFormatter(FormatDateTimeFormatter[] dateTimeFormatters) {
|
public T dateTimeFormatter(FormatDateTimeFormatter[] dateTimeFormatters) {
|
||||||
this.dateTimeFormatters.addAll(newArrayList(dateTimeFormatters));
|
this.dateTimeFormatters.addAll(newArrayList(dateTimeFormatters));
|
||||||
return this;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder dateTimeFormatter(FormatDateTimeFormatter dateTimeFormatter) {
|
public T dateTimeFormatter(FormatDateTimeFormatter dateTimeFormatter) {
|
||||||
this.dateTimeFormatters.add(dateTimeFormatter);
|
this.dateTimeFormatters.add(dateTimeFormatter);
|
||||||
return this;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder add(DynamicTemplate dynamicTemplate) {
|
public T add(XContentMapper.Builder builder) {
|
||||||
this.dynamicTemplates.add(dynamicTemplate);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder add(DynamicTemplate... dynamicTemplate) {
|
|
||||||
for (DynamicTemplate template : dynamicTemplate) {
|
|
||||||
this.dynamicTemplates.add(template);
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder add(XContentMapper.Builder builder) {
|
|
||||||
mappersBuilders.add(builder);
|
mappersBuilders.add(builder);
|
||||||
return this;
|
return this.builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public ObjectMapper build(BuilderContext context) {
|
@Override public Y build(BuilderContext context) {
|
||||||
if (dateTimeFormatters == null) {
|
if (dateTimeFormatters == null) {
|
||||||
dateTimeFormatters = newArrayList();
|
dateTimeFormatters = newArrayList();
|
||||||
} else if (dateTimeFormatters.isEmpty()) {
|
} else if (dateTimeFormatters.isEmpty()) {
|
||||||
|
@ -158,23 +142,27 @@ public class ObjectMapper implements XContentMapper, IncludeInAllMapper {
|
||||||
XContentMapper mapper = builder.build(context);
|
XContentMapper mapper = builder.build(context);
|
||||||
mappers.put(mapper.name(), mapper);
|
mappers.put(mapper.name(), mapper);
|
||||||
}
|
}
|
||||||
ObjectMapper objectMapper = new ObjectMapper(name, enabled, dynamic, pathType,
|
ObjectMapper objectMapper = createMapper(name, enabled, dynamic, pathType,
|
||||||
dateTimeFormatters.toArray(new FormatDateTimeFormatter[dateTimeFormatters.size()]),
|
dateTimeFormatters.toArray(new FormatDateTimeFormatter[dateTimeFormatters.size()]), mappers);
|
||||||
mappers, dynamicTemplates.toArray(new DynamicTemplate[dynamicTemplates.size()]));
|
|
||||||
|
|
||||||
context.path().pathType(origPathType);
|
context.path().pathType(origPathType);
|
||||||
context.path().remove();
|
context.path().remove();
|
||||||
|
|
||||||
objectMapper.includeInAll(includeInAll);
|
objectMapper.includeInAll(includeInAll);
|
||||||
|
|
||||||
return objectMapper;
|
return (Y) objectMapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ObjectMapper createMapper(String name, boolean enabled, boolean dynamic, ContentPath.Type pathType,
|
||||||
|
FormatDateTimeFormatter[] dateTimeFormatters, Map<String, XContentMapper> mappers) {
|
||||||
|
return new ObjectMapper(name, enabled, dynamic, pathType, dateTimeFormatters, mappers);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class TypeParser implements XContentMapper.TypeParser {
|
public static class TypeParser implements XContentMapper.TypeParser {
|
||||||
@Override public XContentMapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
|
@Override public XContentMapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
|
||||||
Map<String, Object> objectNode = node;
|
Map<String, Object> objectNode = node;
|
||||||
ObjectMapper.Builder builder = object(name);
|
ObjectMapper.Builder builder = createBuilder(name);
|
||||||
|
|
||||||
for (Map.Entry<String, Object> entry : objectNode.entrySet()) {
|
for (Map.Entry<String, Object> entry : objectNode.entrySet()) {
|
||||||
String fieldName = Strings.toUnderscoreCase(entry.getKey());
|
String fieldName = Strings.toUnderscoreCase(entry.getKey());
|
||||||
|
@ -187,19 +175,6 @@ public class ObjectMapper implements XContentMapper, IncludeInAllMapper {
|
||||||
if (!type.equals("object")) {
|
if (!type.equals("object")) {
|
||||||
throw new MapperParsingException("Trying to parse an object but has a different type [" + type + "] for [" + name + "]");
|
throw new MapperParsingException("Trying to parse an object but has a different type [" + type + "] for [" + name + "]");
|
||||||
}
|
}
|
||||||
} else if (fieldName.equals("dynamic_templates")) {
|
|
||||||
// "dynamic_templates" : [
|
|
||||||
// {
|
|
||||||
// "match" : "*_test",
|
|
||||||
// "match_mapping_type" : "string",
|
|
||||||
// "mapping" : { "type" : "string", "store" : "yes" }
|
|
||||||
// }
|
|
||||||
// ]
|
|
||||||
List tmplNodes = (List) fieldNode;
|
|
||||||
for (Object tmplNode : tmplNodes) {
|
|
||||||
Map<String, Object> tmpl = (Map<String, Object>) tmplNode;
|
|
||||||
builder.add(DynamicTemplate.parse(tmpl));
|
|
||||||
}
|
|
||||||
} else if (fieldName.equals("date_formats")) {
|
} else if (fieldName.equals("date_formats")) {
|
||||||
List<FormatDateTimeFormatter> dateTimeFormatters = newArrayList();
|
List<FormatDateTimeFormatter> dateTimeFormatters = newArrayList();
|
||||||
if (fieldNode instanceof List) {
|
if (fieldNode instanceof List) {
|
||||||
|
@ -224,6 +199,8 @@ public class ObjectMapper implements XContentMapper, IncludeInAllMapper {
|
||||||
parseProperties(builder, (Map<String, Object>) fieldNode, parserContext);
|
parseProperties(builder, (Map<String, Object>) fieldNode, parserContext);
|
||||||
} else if (fieldName.equals("include_in_all")) {
|
} else if (fieldName.equals("include_in_all")) {
|
||||||
builder.includeInAll(nodeBooleanValue(fieldNode));
|
builder.includeInAll(nodeBooleanValue(fieldNode));
|
||||||
|
} else {
|
||||||
|
processField(builder, fieldName, fieldNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return builder;
|
return builder;
|
||||||
|
@ -256,6 +233,14 @@ public class ObjectMapper implements XContentMapper, IncludeInAllMapper {
|
||||||
objBuilder.add(typeParser.parse(propName, propNode, parserContext));
|
objBuilder.add(typeParser.parse(propName, propNode, parserContext));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected Builder createBuilder(String name) {
|
||||||
|
return object(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void processField(Builder builder, String fieldName, Object fieldNode) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
|
@ -272,8 +257,6 @@ public class ObjectMapper implements XContentMapper, IncludeInAllMapper {
|
||||||
|
|
||||||
private volatile ImmutableMap<String, XContentMapper> mappers = ImmutableMap.of();
|
private volatile ImmutableMap<String, XContentMapper> mappers = ImmutableMap.of();
|
||||||
|
|
||||||
private volatile DynamicTemplate dynamicTemplates[];
|
|
||||||
|
|
||||||
private final Object mutex = new Object();
|
private final Object mutex = new Object();
|
||||||
|
|
||||||
protected ObjectMapper(String name) {
|
protected ObjectMapper(String name) {
|
||||||
|
@ -286,17 +269,16 @@ public class ObjectMapper implements XContentMapper, IncludeInAllMapper {
|
||||||
|
|
||||||
protected ObjectMapper(String name, boolean enabled, boolean dynamic, ContentPath.Type pathType,
|
protected ObjectMapper(String name, boolean enabled, boolean dynamic, ContentPath.Type pathType,
|
||||||
FormatDateTimeFormatter[] dateTimeFormatters) {
|
FormatDateTimeFormatter[] dateTimeFormatters) {
|
||||||
this(name, enabled, dynamic, pathType, dateTimeFormatters, null, null);
|
this(name, enabled, dynamic, pathType, dateTimeFormatters, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectMapper(String name, boolean enabled, boolean dynamic, ContentPath.Type pathType,
|
ObjectMapper(String name, boolean enabled, boolean dynamic, ContentPath.Type pathType,
|
||||||
FormatDateTimeFormatter[] dateTimeFormatters, Map<String, XContentMapper> mappers, DynamicTemplate dynamicTemplates[]) {
|
FormatDateTimeFormatter[] dateTimeFormatters, Map<String, XContentMapper> mappers) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.enabled = enabled;
|
this.enabled = enabled;
|
||||||
this.dynamic = dynamic;
|
this.dynamic = dynamic;
|
||||||
this.pathType = pathType;
|
this.pathType = pathType;
|
||||||
this.dateTimeFormatters = dateTimeFormatters;
|
this.dateTimeFormatters = dateTimeFormatters;
|
||||||
this.dynamicTemplates = dynamicTemplates == null ? new DynamicTemplate[0] : dynamicTemplates;
|
|
||||||
if (mappers != null) {
|
if (mappers != null) {
|
||||||
this.mappers = copyOf(mappers);
|
this.mappers = copyOf(mappers);
|
||||||
}
|
}
|
||||||
|
@ -401,10 +383,9 @@ public class ObjectMapper implements XContentMapper, IncludeInAllMapper {
|
||||||
objectMapper.parse(context);
|
objectMapper.parse(context);
|
||||||
} else {
|
} else {
|
||||||
BuilderContext builderContext = new BuilderContext(context.path());
|
BuilderContext builderContext = new BuilderContext(context.path());
|
||||||
XContentMapper.Builder builder = findTemplateBuilder(context, currentFieldName, "object");
|
XContentMapper.Builder builder = context.root().findTemplateBuilder(context, currentFieldName, "object");
|
||||||
if (builder == null) {
|
if (builder == null) {
|
||||||
builder = XContentMapperBuilders.object(currentFieldName).enabled(true)
|
builder = XContentMapperBuilders.object(currentFieldName).enabled(true)
|
||||||
.add(dynamicTemplates)
|
|
||||||
.dynamic(dynamic).pathType(pathType).dateTimeFormatter(dateTimeFormatters);
|
.dynamic(dynamic).pathType(pathType).dateTimeFormatter(dateTimeFormatters);
|
||||||
}
|
}
|
||||||
objectMapper = builder.build(builderContext);
|
objectMapper = builder.build(builderContext);
|
||||||
|
@ -474,7 +455,7 @@ public class ObjectMapper implements XContentMapper, IncludeInAllMapper {
|
||||||
for (FormatDateTimeFormatter dateTimeFormatter : dateTimeFormatters) {
|
for (FormatDateTimeFormatter dateTimeFormatter : dateTimeFormatters) {
|
||||||
try {
|
try {
|
||||||
dateTimeFormatter.parser().parseMillis(text);
|
dateTimeFormatter.parser().parseMillis(text);
|
||||||
XContentMapper.Builder builder = findTemplateBuilder(context, currentFieldName, "date");
|
XContentMapper.Builder builder = context.root().findTemplateBuilder(context, currentFieldName, "date");
|
||||||
if (builder == null) {
|
if (builder == null) {
|
||||||
builder = dateField(currentFieldName).dateTimeFormatter(dateTimeFormatter);
|
builder = dateField(currentFieldName).dateTimeFormatter(dateTimeFormatter);
|
||||||
}
|
}
|
||||||
|
@ -487,7 +468,7 @@ public class ObjectMapper implements XContentMapper, IncludeInAllMapper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!isDate) {
|
if (!isDate) {
|
||||||
XContentMapper.Builder builder = findTemplateBuilder(context, currentFieldName, "string");
|
XContentMapper.Builder builder = context.root().findTemplateBuilder(context, currentFieldName, "string");
|
||||||
if (builder == null) {
|
if (builder == null) {
|
||||||
builder = stringField(currentFieldName);
|
builder = stringField(currentFieldName);
|
||||||
}
|
}
|
||||||
|
@ -497,53 +478,53 @@ public class ObjectMapper implements XContentMapper, IncludeInAllMapper {
|
||||||
XContentParser.NumberType numberType = context.parser().numberType();
|
XContentParser.NumberType numberType = context.parser().numberType();
|
||||||
if (numberType == XContentParser.NumberType.INT) {
|
if (numberType == XContentParser.NumberType.INT) {
|
||||||
if (context.parser().estimatedNumberType()) {
|
if (context.parser().estimatedNumberType()) {
|
||||||
XContentMapper.Builder builder = findTemplateBuilder(context, currentFieldName, "long");
|
XContentMapper.Builder builder = context.root().findTemplateBuilder(context, currentFieldName, "long");
|
||||||
if (builder == null) {
|
if (builder == null) {
|
||||||
builder = longField(currentFieldName);
|
builder = longField(currentFieldName);
|
||||||
}
|
}
|
||||||
mapper = builder.build(builderContext);
|
mapper = builder.build(builderContext);
|
||||||
} else {
|
} else {
|
||||||
XContentMapper.Builder builder = findTemplateBuilder(context, currentFieldName, "integer");
|
XContentMapper.Builder builder = context.root().findTemplateBuilder(context, currentFieldName, "integer");
|
||||||
if (builder == null) {
|
if (builder == null) {
|
||||||
builder = integerField(currentFieldName);
|
builder = integerField(currentFieldName);
|
||||||
}
|
}
|
||||||
mapper = builder.build(builderContext);
|
mapper = builder.build(builderContext);
|
||||||
}
|
}
|
||||||
} else if (numberType == XContentParser.NumberType.LONG) {
|
} else if (numberType == XContentParser.NumberType.LONG) {
|
||||||
XContentMapper.Builder builder = findTemplateBuilder(context, currentFieldName, "long");
|
XContentMapper.Builder builder = context.root().findTemplateBuilder(context, currentFieldName, "long");
|
||||||
if (builder == null) {
|
if (builder == null) {
|
||||||
builder = longField(currentFieldName);
|
builder = longField(currentFieldName);
|
||||||
}
|
}
|
||||||
mapper = builder.build(builderContext);
|
mapper = builder.build(builderContext);
|
||||||
} else if (numberType == XContentParser.NumberType.FLOAT) {
|
} else if (numberType == XContentParser.NumberType.FLOAT) {
|
||||||
if (context.parser().estimatedNumberType()) {
|
if (context.parser().estimatedNumberType()) {
|
||||||
XContentMapper.Builder builder = findTemplateBuilder(context, currentFieldName, "double");
|
XContentMapper.Builder builder = context.root().findTemplateBuilder(context, currentFieldName, "double");
|
||||||
if (builder == null) {
|
if (builder == null) {
|
||||||
builder = doubleField(currentFieldName);
|
builder = doubleField(currentFieldName);
|
||||||
}
|
}
|
||||||
mapper = builder.build(builderContext);
|
mapper = builder.build(builderContext);
|
||||||
} else {
|
} else {
|
||||||
XContentMapper.Builder builder = findTemplateBuilder(context, currentFieldName, "float");
|
XContentMapper.Builder builder = context.root().findTemplateBuilder(context, currentFieldName, "float");
|
||||||
if (builder == null) {
|
if (builder == null) {
|
||||||
builder = floatField(currentFieldName);
|
builder = floatField(currentFieldName);
|
||||||
}
|
}
|
||||||
mapper = builder.build(builderContext);
|
mapper = builder.build(builderContext);
|
||||||
}
|
}
|
||||||
} else if (numberType == XContentParser.NumberType.DOUBLE) {
|
} else if (numberType == XContentParser.NumberType.DOUBLE) {
|
||||||
XContentMapper.Builder builder = findTemplateBuilder(context, currentFieldName, "double");
|
XContentMapper.Builder builder = context.root().findTemplateBuilder(context, currentFieldName, "double");
|
||||||
if (builder == null) {
|
if (builder == null) {
|
||||||
builder = doubleField(currentFieldName);
|
builder = doubleField(currentFieldName);
|
||||||
}
|
}
|
||||||
mapper = builder.build(builderContext);
|
mapper = builder.build(builderContext);
|
||||||
}
|
}
|
||||||
} else if (token == XContentParser.Token.VALUE_BOOLEAN) {
|
} else if (token == XContentParser.Token.VALUE_BOOLEAN) {
|
||||||
XContentMapper.Builder builder = findTemplateBuilder(context, currentFieldName, "boolean");
|
XContentMapper.Builder builder = context.root().findTemplateBuilder(context, currentFieldName, "boolean");
|
||||||
if (builder == null) {
|
if (builder == null) {
|
||||||
builder = booleanField(currentFieldName);
|
builder = booleanField(currentFieldName);
|
||||||
}
|
}
|
||||||
mapper = builder.build(builderContext);
|
mapper = builder.build(builderContext);
|
||||||
} else {
|
} else {
|
||||||
XContentMapper.Builder builder = findTemplateBuilder(context, currentFieldName, null);
|
XContentMapper.Builder builder = context.root().findTemplateBuilder(context, currentFieldName, null);
|
||||||
if (builder != null) {
|
if (builder != null) {
|
||||||
mapper = builder.build(builderContext);
|
mapper = builder.build(builderContext);
|
||||||
} else {
|
} else {
|
||||||
|
@ -563,43 +544,15 @@ public class ObjectMapper implements XContentMapper, IncludeInAllMapper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private XContentMapper.Builder findTemplateBuilder(ParseContext context, String name, String dynamicType) {
|
|
||||||
DynamicTemplate dynamicTemplate = findTemplate(name, dynamicType);
|
|
||||||
if (dynamicTemplate == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
XContentMapper.TypeParser.ParserContext parserContext = context.docMapperParser().parserContext();
|
|
||||||
return parserContext.typeParser(dynamicTemplate.mappingType(dynamicType)).parse(name, dynamicTemplate.mappingForName(name, dynamicType), parserContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
private DynamicTemplate findTemplate(String name, String dynamicType) {
|
|
||||||
for (DynamicTemplate dynamicTemplate : dynamicTemplates) {
|
|
||||||
if (dynamicTemplate.match(name, dynamicType)) {
|
|
||||||
return dynamicTemplate;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public void merge(XContentMapper mergeWith, MergeContext mergeContext) throws MergeMappingException {
|
@Override public void merge(XContentMapper mergeWith, MergeContext mergeContext) throws MergeMappingException {
|
||||||
if (!(mergeWith instanceof ObjectMapper)) {
|
if (!(mergeWith instanceof ObjectMapper)) {
|
||||||
mergeContext.addConflict("Can't merge a non object mapping [" + mergeWith.name() + "] with an object mapping [" + name() + "]");
|
mergeContext.addConflict("Can't merge a non object mapping [" + mergeWith.name() + "] with an object mapping [" + name() + "]");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ObjectMapper mergeWithObject = (ObjectMapper) mergeWith;
|
ObjectMapper mergeWithObject = (ObjectMapper) mergeWith;
|
||||||
if (!mergeContext.mergeFlags().simulate()) {
|
|
||||||
// merge them
|
doMerge(mergeWithObject, mergeContext);
|
||||||
List<DynamicTemplate> mergedTemplates = Lists.newArrayList(Arrays.asList(this.dynamicTemplates));
|
|
||||||
for (DynamicTemplate template : mergeWithObject.dynamicTemplates) {
|
|
||||||
int index = mergedTemplates.indexOf(template);
|
|
||||||
if (index == -1) {
|
|
||||||
mergedTemplates.add(template);
|
|
||||||
} else {
|
|
||||||
mergedTemplates.set(index, template);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.dynamicTemplates = mergedTemplates.toArray(new DynamicTemplate[mergedTemplates.size()]);
|
|
||||||
}
|
|
||||||
synchronized (mutex) {
|
synchronized (mutex) {
|
||||||
for (XContentMapper mergeWithMapper : mergeWithObject.mappers.values()) {
|
for (XContentMapper mergeWithMapper : mergeWithObject.mappers.values()) {
|
||||||
XContentMapper mergeIntoMapper = mappers.get(mergeWithMapper.name());
|
XContentMapper mergeIntoMapper = mappers.get(mergeWithMapper.name());
|
||||||
|
@ -632,6 +585,10 @@ public class ObjectMapper implements XContentMapper, IncludeInAllMapper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void doMerge(ObjectMapper mergeWith, MergeContext mergeContext) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Override public void toXContent(XContentBuilder builder, Params params) throws IOException {
|
@Override public void toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||||
toXContent(builder, params, XContentMapper.EMPTY_ARRAY);
|
toXContent(builder, params, XContentMapper.EMPTY_ARRAY);
|
||||||
}
|
}
|
||||||
|
@ -645,13 +602,8 @@ public class ObjectMapper implements XContentMapper, IncludeInAllMapper {
|
||||||
if (includeInAll != null) {
|
if (includeInAll != null) {
|
||||||
builder.field("include_in_all", includeInAll);
|
builder.field("include_in_all", includeInAll);
|
||||||
}
|
}
|
||||||
if (dynamicTemplates != null && dynamicTemplates.length > 0) {
|
|
||||||
builder.startArray("dynamic_templates");
|
doXContent(builder, params);
|
||||||
for (DynamicTemplate dynamicTemplate : dynamicTemplates) {
|
|
||||||
builder.map(dynamicTemplate.conf());
|
|
||||||
}
|
|
||||||
builder.endArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dateTimeFormatters.length > 0) {
|
if (dateTimeFormatters.length > 0) {
|
||||||
builder.startArray("date_formats");
|
builder.startArray("date_formats");
|
||||||
|
@ -684,4 +636,8 @@ public class ObjectMapper implements XContentMapper, IncludeInAllMapper {
|
||||||
}
|
}
|
||||||
builder.endObject();
|
builder.endObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void doXContent(XContentBuilder builder, Params params) throws IOException {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -124,6 +124,10 @@ public class ParseContext {
|
||||||
return this.document;
|
return this.document;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public RootObjectMapper root() {
|
||||||
|
return docMapper.root();
|
||||||
|
}
|
||||||
|
|
||||||
public XContentDocumentMapper docMapper() {
|
public XContentDocumentMapper docMapper() {
|
||||||
return this.docMapper;
|
return this.docMapper;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,141 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import org.elasticsearch.common.collect.Lists;
|
||||||
|
import org.elasticsearch.common.joda.FormatDateTimeFormatter;
|
||||||
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static org.elasticsearch.common.collect.Lists.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author kimchy (shay.banon)
|
||||||
|
*/
|
||||||
|
public class RootObjectMapper extends ObjectMapper {
|
||||||
|
|
||||||
|
public static class Builder extends ObjectMapper.Builder<Builder, RootObjectMapper> {
|
||||||
|
|
||||||
|
protected final List<DynamicTemplate> dynamicTemplates = newArrayList();
|
||||||
|
|
||||||
|
public Builder(String name) {
|
||||||
|
super(name);
|
||||||
|
this.builder = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder add(DynamicTemplate dynamicTemplate) {
|
||||||
|
this.dynamicTemplates.add(dynamicTemplate);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder add(DynamicTemplate... dynamicTemplate) {
|
||||||
|
for (DynamicTemplate template : dynamicTemplate) {
|
||||||
|
this.dynamicTemplates.add(template);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override protected ObjectMapper createMapper(String name, boolean enabled, boolean dynamic, ContentPath.Type pathType, FormatDateTimeFormatter[] dateTimeFormatters, Map<String, XContentMapper> mappers) {
|
||||||
|
return new RootObjectMapper(name, enabled, dynamic, pathType, dateTimeFormatters, mappers, dynamicTemplates.toArray(new DynamicTemplate[dynamicTemplates.size()]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class TypeParser extends ObjectMapper.TypeParser {
|
||||||
|
|
||||||
|
@Override protected ObjectMapper.Builder createBuilder(String name) {
|
||||||
|
return new Builder(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override protected void processField(ObjectMapper.Builder builder, String fieldName, Object fieldNode) {
|
||||||
|
if (fieldName.equals("dynamic_templates")) {
|
||||||
|
// "dynamic_templates" : [
|
||||||
|
// {
|
||||||
|
// "match" : "*_test",
|
||||||
|
// "match_mapping_type" : "string",
|
||||||
|
// "mapping" : { "type" : "string", "store" : "yes" }
|
||||||
|
// }
|
||||||
|
// ]
|
||||||
|
List tmplNodes = (List) fieldNode;
|
||||||
|
for (Object tmplNode : tmplNodes) {
|
||||||
|
Map<String, Object> tmpl = (Map<String, Object>) tmplNode;
|
||||||
|
((Builder) builder).add(DynamicTemplate.parse(tmpl));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private volatile DynamicTemplate dynamicTemplates[];
|
||||||
|
|
||||||
|
RootObjectMapper(String name, boolean enabled, boolean dynamic, ContentPath.Type pathType,
|
||||||
|
FormatDateTimeFormatter[] dateTimeFormatters, Map<String, XContentMapper> mappers, DynamicTemplate dynamicTemplates[]) {
|
||||||
|
super(name, enabled, dynamic, pathType, dateTimeFormatters, mappers);
|
||||||
|
this.dynamicTemplates = dynamicTemplates;
|
||||||
|
}
|
||||||
|
|
||||||
|
public XContentMapper.Builder findTemplateBuilder(ParseContext context, String name, String dynamicType) {
|
||||||
|
DynamicTemplate dynamicTemplate = findTemplate(name, dynamicType);
|
||||||
|
if (dynamicTemplate == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
XContentMapper.TypeParser.ParserContext parserContext = context.docMapperParser().parserContext();
|
||||||
|
return parserContext.typeParser(dynamicTemplate.mappingType(dynamicType)).parse(name, dynamicTemplate.mappingForName(name, dynamicType), parserContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DynamicTemplate findTemplate(String name, String dynamicType) {
|
||||||
|
for (DynamicTemplate dynamicTemplate : dynamicTemplates) {
|
||||||
|
if (dynamicTemplate.match(name, dynamicType)) {
|
||||||
|
return dynamicTemplate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override protected void doMerge(ObjectMapper mergeWith, MergeContext mergeContext) {
|
||||||
|
RootObjectMapper mergeWithObject = (RootObjectMapper) mergeWith;
|
||||||
|
if (!mergeContext.mergeFlags().simulate()) {
|
||||||
|
// merge them
|
||||||
|
List<DynamicTemplate> mergedTemplates = Lists.newArrayList(Arrays.asList(this.dynamicTemplates));
|
||||||
|
for (DynamicTemplate template : mergeWithObject.dynamicTemplates) {
|
||||||
|
int index = mergedTemplates.indexOf(template);
|
||||||
|
if (index == -1) {
|
||||||
|
mergedTemplates.add(template);
|
||||||
|
} else {
|
||||||
|
mergedTemplates.set(index, template);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.dynamicTemplates = mergedTemplates.toArray(new DynamicTemplate[mergedTemplates.size()]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override protected void doXContent(XContentBuilder builder, Params params) throws IOException {
|
||||||
|
if (dynamicTemplates != null && dynamicTemplates.length > 0) {
|
||||||
|
builder.startArray("dynamic_templates");
|
||||||
|
for (DynamicTemplate dynamicTemplate : dynamicTemplates) {
|
||||||
|
builder.map(dynamicTemplate.conf());
|
||||||
|
}
|
||||||
|
builder.endArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -64,13 +64,13 @@ public class XContentDocumentMapper implements DocumentMapper, ToXContent {
|
||||||
|
|
||||||
private final String index;
|
private final String index;
|
||||||
|
|
||||||
private final ObjectMapper rootObjectMapper;
|
private final RootObjectMapper rootObjectMapper;
|
||||||
|
|
||||||
private ImmutableMap<String, Object> attributes = ImmutableMap.of();
|
private ImmutableMap<String, Object> attributes = ImmutableMap.of();
|
||||||
|
|
||||||
private XContentMapper.BuilderContext builderContext = new XContentMapper.BuilderContext(new ContentPath(1));
|
private XContentMapper.BuilderContext builderContext = new XContentMapper.BuilderContext(new ContentPath(1));
|
||||||
|
|
||||||
public Builder(String index, ObjectMapper.Builder builder) {
|
public Builder(String index, RootObjectMapper.Builder builder) {
|
||||||
this.index = index;
|
this.index = index;
|
||||||
this.rootObjectMapper = builder.build(builderContext);
|
this.rootObjectMapper = builder.build(builderContext);
|
||||||
}
|
}
|
||||||
|
@ -171,7 +171,7 @@ public class XContentDocumentMapper implements DocumentMapper, ToXContent {
|
||||||
|
|
||||||
private final AllFieldMapper allFieldMapper;
|
private final AllFieldMapper allFieldMapper;
|
||||||
|
|
||||||
private final ObjectMapper rootObjectMapper;
|
private final RootObjectMapper rootObjectMapper;
|
||||||
|
|
||||||
private final Analyzer indexAnalyzer;
|
private final Analyzer indexAnalyzer;
|
||||||
|
|
||||||
|
@ -186,7 +186,7 @@ public class XContentDocumentMapper implements DocumentMapper, ToXContent {
|
||||||
private final Object mutex = new Object();
|
private final Object mutex = new Object();
|
||||||
|
|
||||||
public XContentDocumentMapper(String index, XContentDocumentMapperParser docMapperParser,
|
public XContentDocumentMapper(String index, XContentDocumentMapperParser docMapperParser,
|
||||||
ObjectMapper rootObjectMapper,
|
RootObjectMapper rootObjectMapper,
|
||||||
ImmutableMap<String, Object> attributes,
|
ImmutableMap<String, Object> attributes,
|
||||||
UidFieldMapper uidFieldMapper,
|
UidFieldMapper uidFieldMapper,
|
||||||
IdFieldMapper idFieldMapper,
|
IdFieldMapper idFieldMapper,
|
||||||
|
@ -260,6 +260,10 @@ public class XContentDocumentMapper implements DocumentMapper, ToXContent {
|
||||||
return this.mappingSource;
|
return this.mappingSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public RootObjectMapper root() {
|
||||||
|
return this.rootObjectMapper;
|
||||||
|
}
|
||||||
|
|
||||||
@Override public org.elasticsearch.index.mapper.UidFieldMapper uidMapper() {
|
@Override public org.elasticsearch.index.mapper.UidFieldMapper uidMapper() {
|
||||||
return this.uidFieldMapper;
|
return this.uidFieldMapper;
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,7 +53,7 @@ public class XContentDocumentMapperParser extends AbstractIndexComponent impleme
|
||||||
|
|
||||||
private final AnalysisService analysisService;
|
private final AnalysisService analysisService;
|
||||||
|
|
||||||
private final ObjectMapper.TypeParser rootObjectTypeParser = new ObjectMapper.TypeParser();
|
private final RootObjectMapper.TypeParser rootObjectTypeParser = new RootObjectMapper.TypeParser();
|
||||||
|
|
||||||
private final Object typeParsersMutex = new Object();
|
private final Object typeParsersMutex = new Object();
|
||||||
|
|
||||||
|
@ -127,7 +127,7 @@ public class XContentDocumentMapperParser extends AbstractIndexComponent impleme
|
||||||
|
|
||||||
XContentMapper.TypeParser.ParserContext parserContext = new XContentMapper.TypeParser.ParserContext(analysisService, typeParsers);
|
XContentMapper.TypeParser.ParserContext parserContext = new XContentMapper.TypeParser.ParserContext(analysisService, typeParsers);
|
||||||
|
|
||||||
XContentDocumentMapper.Builder docBuilder = doc(index.name(), (ObjectMapper.Builder) rootObjectTypeParser.parse(type, mapping, parserContext));
|
XContentDocumentMapper.Builder docBuilder = doc(index.name(), (RootObjectMapper.Builder) rootObjectTypeParser.parse(type, mapping, parserContext));
|
||||||
|
|
||||||
for (Map.Entry<String, Object> entry : mapping.entrySet()) {
|
for (Map.Entry<String, Object> entry : mapping.entrySet()) {
|
||||||
String fieldName = Strings.toUnderscoreCase(entry.getKey());
|
String fieldName = Strings.toUnderscoreCase(entry.getKey());
|
||||||
|
|
|
@ -28,7 +28,7 @@ public final class XContentMapperBuilders {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static XContentDocumentMapper.Builder doc(String index, ObjectMapper.Builder objectBuilder) {
|
public static XContentDocumentMapper.Builder doc(String index, RootObjectMapper.Builder objectBuilder) {
|
||||||
return new XContentDocumentMapper.Builder(index, objectBuilder);
|
return new XContentDocumentMapper.Builder(index, objectBuilder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,6 +64,10 @@ public final class XContentMapperBuilders {
|
||||||
return new MultiFieldMapper.Builder(name);
|
return new MultiFieldMapper.Builder(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static RootObjectMapper.Builder rootObject(String name) {
|
||||||
|
return new RootObjectMapper.Builder(name);
|
||||||
|
}
|
||||||
|
|
||||||
public static ObjectMapper.Builder object(String name) {
|
public static ObjectMapper.Builder object(String name) {
|
||||||
return new ObjectMapper.Builder(name);
|
return new ObjectMapper.Builder(name);
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,4 +86,59 @@ public class SimpleDynamicTemplatesTests {
|
||||||
fieldMappers = docMapper.mappers().fullName("multi2.org");
|
fieldMappers = docMapper.mappers().fullName("multi2.org");
|
||||||
assertThat(fieldMappers.mappers().size(), equalTo(1));
|
assertThat(fieldMappers.mappers().size(), equalTo(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test public void testSimpleWithXContentTraverse() throws Exception {
|
||||||
|
String mapping = copyToStringFromClasspath("/org/elasticsearch/index/mapper/xcontent/dynamictemplate/simple/test-mapping.json");
|
||||||
|
XContentDocumentMapper docMapper = MapperTests.newParser().parse(mapping);
|
||||||
|
docMapper.refreshSource();
|
||||||
|
docMapper = MapperTests.newParser().parse(docMapper.mappingSource().string());
|
||||||
|
|
||||||
|
byte[] json = copyToBytesFromClasspath("/org/elasticsearch/index/mapper/xcontent/dynamictemplate/simple/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.isIndexed(), equalTo(true));
|
||||||
|
assertThat(f.isTokenized(), equalTo(false));
|
||||||
|
|
||||||
|
FieldMappers fieldMappers = docMapper.mappers().fullName("name");
|
||||||
|
assertThat(fieldMappers.mappers().size(), equalTo(1));
|
||||||
|
|
||||||
|
f = doc.getField("multi1");
|
||||||
|
assertThat(f.name(), equalTo("multi1"));
|
||||||
|
assertThat(f.stringValue(), equalTo("multi 1"));
|
||||||
|
assertThat(f.isIndexed(), equalTo(true));
|
||||||
|
assertThat(f.isTokenized(), equalTo(true));
|
||||||
|
|
||||||
|
fieldMappers = docMapper.mappers().fullName("multi1");
|
||||||
|
assertThat(fieldMappers.mappers().size(), equalTo(1));
|
||||||
|
|
||||||
|
f = doc.getField("multi1.org");
|
||||||
|
assertThat(f.name(), equalTo("multi1.org"));
|
||||||
|
assertThat(f.stringValue(), equalTo("multi 1"));
|
||||||
|
assertThat(f.isIndexed(), equalTo(true));
|
||||||
|
assertThat(f.isTokenized(), equalTo(false));
|
||||||
|
|
||||||
|
fieldMappers = docMapper.mappers().fullName("multi1.org");
|
||||||
|
assertThat(fieldMappers.mappers().size(), equalTo(1));
|
||||||
|
|
||||||
|
f = doc.getField("multi2");
|
||||||
|
assertThat(f.name(), equalTo("multi2"));
|
||||||
|
assertThat(f.stringValue(), equalTo("multi 2"));
|
||||||
|
assertThat(f.isIndexed(), equalTo(true));
|
||||||
|
assertThat(f.isTokenized(), equalTo(true));
|
||||||
|
|
||||||
|
fieldMappers = docMapper.mappers().fullName("multi2");
|
||||||
|
assertThat(fieldMappers.mappers().size(), equalTo(1));
|
||||||
|
|
||||||
|
f = doc.getField("multi2.org");
|
||||||
|
assertThat(f.name(), equalTo("multi2.org"));
|
||||||
|
assertThat(f.stringValue(), equalTo("multi 2"));
|
||||||
|
assertThat(f.isIndexed(), equalTo(true));
|
||||||
|
assertThat(f.isTokenized(), equalTo(false));
|
||||||
|
|
||||||
|
fieldMappers = docMapper.mappers().fullName("multi2.org");
|
||||||
|
assertThat(fieldMappers.mappers().size(), equalTo(1));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,7 +71,8 @@ public class MultiFieldTests {
|
||||||
|
|
||||||
@Test public void testBuildThenParse() throws Exception {
|
@Test public void testBuildThenParse() throws Exception {
|
||||||
XContentDocumentMapperParser mapperParser = MapperTests.newParser();
|
XContentDocumentMapperParser mapperParser = MapperTests.newParser();
|
||||||
XContentDocumentMapper builderDocMapper = doc("test", object("person").add(
|
|
||||||
|
XContentDocumentMapper builderDocMapper = doc("test", rootObject("person").add(
|
||||||
multiField("name")
|
multiField("name")
|
||||||
.add(stringField("name").store(Field.Store.YES))
|
.add(stringField("name").store(Field.Store.YES))
|
||||||
.add(stringField("indexed").index(Field.Index.ANALYZED))
|
.add(stringField("indexed").index(Field.Index.ANALYZED))
|
||||||
|
|
|
@ -41,7 +41,7 @@ public class SimpleMapperTests {
|
||||||
@Test public void testSimpleMapper() throws Exception {
|
@Test public void testSimpleMapper() throws Exception {
|
||||||
XContentDocumentMapperParser mapperParser = MapperTests.newParser();
|
XContentDocumentMapperParser mapperParser = MapperTests.newParser();
|
||||||
XContentDocumentMapper docMapper = doc("test",
|
XContentDocumentMapper docMapper = doc("test",
|
||||||
object("person")
|
rootObject("person")
|
||||||
.add(object("name").add(stringField("first").store(YES).index(Field.Index.NO)))
|
.add(object("name").add(stringField("first").store(YES).index(Field.Index.NO)))
|
||||||
).sourceField(source()).build(mapperParser);
|
).sourceField(source()).build(mapperParser);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue