more refactoring to generalize root level field mappers
This commit is contained in:
parent
821c3524a2
commit
a9bc775213
|
@ -48,10 +48,7 @@ import org.elasticsearch.index.mapper.object.ObjectMapper;
|
||||||
import org.elasticsearch.index.mapper.object.RootObjectMapper;
|
import org.elasticsearch.index.mapper.object.RootObjectMapper;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
@ -140,13 +137,7 @@ public class DocumentMapper implements ToXContent {
|
||||||
|
|
||||||
private IdFieldMapper idFieldMapper = new IdFieldMapper();
|
private IdFieldMapper idFieldMapper = new IdFieldMapper();
|
||||||
|
|
||||||
private RoutingFieldMapper routingFieldMapper = new RoutingFieldMapper();
|
private Map<Class<? extends RootMapper>, RootMapper> rootMappers = Maps.newHashMap();
|
||||||
|
|
||||||
private BoostFieldMapper boostFieldMapper = new BoostFieldMapper();
|
|
||||||
|
|
||||||
private ParentFieldMapper parentFieldMapper = null;
|
|
||||||
|
|
||||||
private Map<String, RootMapper> rootMappers = new HashMap<String, RootMapper>();
|
|
||||||
|
|
||||||
private NamedAnalyzer indexAnalyzer;
|
private NamedAnalyzer indexAnalyzer;
|
||||||
|
|
||||||
|
@ -170,12 +161,15 @@ public class DocumentMapper implements ToXContent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// add default mappers
|
// add default mappers
|
||||||
this.rootMappers.put(SizeFieldMapper.NAME, new SizeFieldMapper());
|
this.rootMappers.put(SizeFieldMapper.class, new SizeFieldMapper());
|
||||||
this.rootMappers.put(IndexFieldMapper.NAME, new IndexFieldMapper());
|
this.rootMappers.put(IndexFieldMapper.class, new IndexFieldMapper());
|
||||||
this.rootMappers.put(SourceFieldMapper.NAME, new SourceFieldMapper());
|
this.rootMappers.put(SourceFieldMapper.class, new SourceFieldMapper());
|
||||||
this.rootMappers.put(TypeFieldMapper.NAME, new TypeFieldMapper());
|
this.rootMappers.put(TypeFieldMapper.class, new TypeFieldMapper());
|
||||||
this.rootMappers.put(AllFieldMapper.NAME, new AllFieldMapper());
|
this.rootMappers.put(AllFieldMapper.class, new AllFieldMapper());
|
||||||
this.rootMappers.put(AnalyzerMapper.NAME, new AnalyzerMapper());
|
this.rootMappers.put(AnalyzerMapper.class, new AnalyzerMapper());
|
||||||
|
this.rootMappers.put(BoostFieldMapper.class, new BoostFieldMapper());
|
||||||
|
this.rootMappers.put(RoutingFieldMapper.class, new RoutingFieldMapper());
|
||||||
|
// don't add parent field, by default its "null"
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder meta(ImmutableMap<String, Object> meta) {
|
public Builder meta(ImmutableMap<String, Object> meta) {
|
||||||
|
@ -184,7 +178,8 @@ public class DocumentMapper implements ToXContent {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder put(RootMapper.Builder mapper) {
|
public Builder put(RootMapper.Builder mapper) {
|
||||||
rootMappers.put(mapper.name(), (RootMapper) mapper.build(builderContext));
|
RootMapper rootMapper = (RootMapper) mapper.build(builderContext);
|
||||||
|
rootMappers.put(rootMapper.getClass(), rootMapper);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,21 +193,6 @@ public class DocumentMapper implements ToXContent {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder routingField(RoutingFieldMapper.Builder builder) {
|
|
||||||
this.routingFieldMapper = builder.build(builderContext);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder parentFiled(ParentFieldMapper.Builder builder) {
|
|
||||||
this.parentFieldMapper = builder.build(builderContext);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder boostField(BoostFieldMapper.Builder builder) {
|
|
||||||
this.boostFieldMapper = builder.build(builderContext);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder indexAnalyzer(NamedAnalyzer indexAnalyzer) {
|
public Builder indexAnalyzer(NamedAnalyzer indexAnalyzer) {
|
||||||
this.indexAnalyzer = indexAnalyzer;
|
this.indexAnalyzer = indexAnalyzer;
|
||||||
return this;
|
return this;
|
||||||
|
@ -234,7 +214,7 @@ public class DocumentMapper implements ToXContent {
|
||||||
public DocumentMapper build(DocumentMapperParser docMapperParser) {
|
public DocumentMapper build(DocumentMapperParser docMapperParser) {
|
||||||
Preconditions.checkNotNull(rootObjectMapper, "Mapper builder must have the root object mapper set");
|
Preconditions.checkNotNull(rootObjectMapper, "Mapper builder must have the root object mapper set");
|
||||||
return new DocumentMapper(index, docMapperParser, rootObjectMapper, meta, uidFieldMapper, idFieldMapper,
|
return new DocumentMapper(index, docMapperParser, rootObjectMapper, meta, uidFieldMapper, idFieldMapper,
|
||||||
parentFieldMapper, routingFieldMapper, indexAnalyzer, searchAnalyzer, boostFieldMapper,
|
indexAnalyzer, searchAnalyzer,
|
||||||
rootMappers);
|
rootMappers);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -260,15 +240,9 @@ public class DocumentMapper implements ToXContent {
|
||||||
|
|
||||||
private final IdFieldMapper idFieldMapper;
|
private final IdFieldMapper idFieldMapper;
|
||||||
|
|
||||||
private final RoutingFieldMapper routingFieldMapper;
|
|
||||||
|
|
||||||
private final ParentFieldMapper parentFieldMapper;
|
|
||||||
|
|
||||||
private final BoostFieldMapper boostFieldMapper;
|
|
||||||
|
|
||||||
private final RootObjectMapper rootObjectMapper;
|
private final RootObjectMapper rootObjectMapper;
|
||||||
|
|
||||||
private final ImmutableMap<String, RootMapper> rootMappers;
|
private final ImmutableMap<Class<? extends RootMapper>, RootMapper> rootMappers;
|
||||||
private final RootMapper[] rootMappersOrdered;
|
private final RootMapper[] rootMappersOrdered;
|
||||||
private final RootMapper[] rootMappersNotIncludedInObject;
|
private final RootMapper[] rootMappersNotIncludedInObject;
|
||||||
|
|
||||||
|
@ -295,11 +269,8 @@ public class DocumentMapper implements ToXContent {
|
||||||
ImmutableMap<String, Object> meta,
|
ImmutableMap<String, Object> meta,
|
||||||
UidFieldMapper uidFieldMapper,
|
UidFieldMapper uidFieldMapper,
|
||||||
IdFieldMapper idFieldMapper,
|
IdFieldMapper idFieldMapper,
|
||||||
@Nullable ParentFieldMapper parentFieldMapper,
|
|
||||||
RoutingFieldMapper routingFieldMapper,
|
|
||||||
NamedAnalyzer indexAnalyzer, NamedAnalyzer searchAnalyzer,
|
NamedAnalyzer indexAnalyzer, NamedAnalyzer searchAnalyzer,
|
||||||
@Nullable BoostFieldMapper boostFieldMapper,
|
Map<Class<? extends RootMapper>, RootMapper> rootMappers) {
|
||||||
Map<String, RootMapper> rootMappers) {
|
|
||||||
this.index = index;
|
this.index = index;
|
||||||
this.type = rootObjectMapper.name();
|
this.type = rootObjectMapper.name();
|
||||||
this.docMapperParser = docMapperParser;
|
this.docMapperParser = docMapperParser;
|
||||||
|
@ -307,9 +278,6 @@ public class DocumentMapper implements ToXContent {
|
||||||
this.rootObjectMapper = rootObjectMapper;
|
this.rootObjectMapper = rootObjectMapper;
|
||||||
this.uidFieldMapper = uidFieldMapper;
|
this.uidFieldMapper = uidFieldMapper;
|
||||||
this.idFieldMapper = idFieldMapper;
|
this.idFieldMapper = idFieldMapper;
|
||||||
this.parentFieldMapper = parentFieldMapper;
|
|
||||||
this.routingFieldMapper = routingFieldMapper;
|
|
||||||
this.boostFieldMapper = boostFieldMapper;
|
|
||||||
|
|
||||||
this.rootMappers = ImmutableMap.copyOf(rootMappers);
|
this.rootMappers = ImmutableMap.copyOf(rootMappers);
|
||||||
this.rootMappersOrdered = rootMappers.values().toArray(new RootMapper[rootMappers.values().size()]);
|
this.rootMappersOrdered = rootMappers.values().toArray(new RootMapper[rootMappers.values().size()]);
|
||||||
|
@ -327,15 +295,10 @@ public class DocumentMapper implements ToXContent {
|
||||||
this.typeFilter = typeMapper().fieldFilter(type);
|
this.typeFilter = typeMapper().fieldFilter(type);
|
||||||
|
|
||||||
rootObjectMapper.putMapper(idFieldMapper);
|
rootObjectMapper.putMapper(idFieldMapper);
|
||||||
if (boostFieldMapper != null) {
|
if (rootMapper(ParentFieldMapper.class) != null) {
|
||||||
rootObjectMapper.putMapper(boostFieldMapper);
|
// mark the routing field mapper as required
|
||||||
|
rootMapper(RoutingFieldMapper.class).markAsRequired();
|
||||||
}
|
}
|
||||||
if (parentFieldMapper != null) {
|
|
||||||
rootObjectMapper.putMapper(parentFieldMapper);
|
|
||||||
// also, mark the routing as required!
|
|
||||||
routingFieldMapper.markAsRequired();
|
|
||||||
}
|
|
||||||
rootObjectMapper.putMapper(routingFieldMapper);
|
|
||||||
|
|
||||||
final List<FieldMapper> tempFieldMappers = newArrayList();
|
final List<FieldMapper> tempFieldMappers = newArrayList();
|
||||||
for (RootMapper rootMapper : rootMappersOrdered) {
|
for (RootMapper rootMapper : rootMappersOrdered) {
|
||||||
|
@ -395,28 +358,28 @@ public class DocumentMapper implements ToXContent {
|
||||||
return this.uidFieldMapper;
|
return this.uidFieldMapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings({"unchecked"}) public <T extends RootMapper> T rootMapper(String name) {
|
@SuppressWarnings({"unchecked"}) public <T extends RootMapper> T rootMapper(Class<T> type) {
|
||||||
return (T) rootMappers.get(name);
|
return (T) rootMappers.get(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypeFieldMapper typeMapper() {
|
public TypeFieldMapper typeMapper() {
|
||||||
return rootMapper(TypeFieldMapper.NAME);
|
return rootMapper(TypeFieldMapper.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SourceFieldMapper sourceMapper() {
|
public SourceFieldMapper sourceMapper() {
|
||||||
return rootMapper(SourceFieldMapper.NAME);
|
return rootMapper(SourceFieldMapper.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public AllFieldMapper allFieldMapper() {
|
public AllFieldMapper allFieldMapper() {
|
||||||
return rootMapper(AllFieldMapper.NAME);
|
return rootMapper(AllFieldMapper.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public RoutingFieldMapper routingFieldMapper() {
|
public RoutingFieldMapper routingFieldMapper() {
|
||||||
return this.routingFieldMapper;
|
return rootMapper(RoutingFieldMapper.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ParentFieldMapper parentFieldMapper() {
|
public ParentFieldMapper parentFieldMapper() {
|
||||||
return this.parentFieldMapper;
|
return rootMapper(ParentFieldMapper.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Analyzer indexAnalyzer() {
|
public Analyzer indexAnalyzer() {
|
||||||
|
@ -515,10 +478,6 @@ public class DocumentMapper implements ToXContent {
|
||||||
context.id(source.id());
|
context.id(source.id());
|
||||||
uidFieldMapper.parse(context);
|
uidFieldMapper.parse(context);
|
||||||
}
|
}
|
||||||
if (source.routing() != null) {
|
|
||||||
context.externalValue(source.routing());
|
|
||||||
routingFieldMapper.parse(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!emptyDoc) {
|
if (!emptyDoc) {
|
||||||
rootObjectMapper.parse(context);
|
rootObjectMapper.parse(context);
|
||||||
|
@ -563,17 +522,9 @@ public class DocumentMapper implements ToXContent {
|
||||||
rootMapper.postParse(context);
|
rootMapper.postParse(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parentFieldMapper != null) {
|
|
||||||
parentFieldMapper.parse(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
for (RootMapper rootMapper : rootMappersOrdered) {
|
for (RootMapper rootMapper : rootMappersOrdered) {
|
||||||
rootMapper.validate(context);
|
rootMapper.validate(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
// validate aggregated mappers (TODO: need to be added as a phase to any field mapper)
|
|
||||||
routingFieldMapper.validate(context);
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new MapperParsingException("Failed to parse", e);
|
throw new MapperParsingException("Failed to parse", e);
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -638,7 +589,7 @@ public class DocumentMapper implements ToXContent {
|
||||||
MergeContext mergeContext = new MergeContext(this, mergeFlags);
|
MergeContext mergeContext = new MergeContext(this, mergeFlags);
|
||||||
rootObjectMapper.merge(mergeWith.rootObjectMapper, mergeContext);
|
rootObjectMapper.merge(mergeWith.rootObjectMapper, mergeContext);
|
||||||
|
|
||||||
for (Map.Entry<String, RootMapper> entry : rootMappers.entrySet()) {
|
for (Map.Entry<Class<? extends RootMapper>, RootMapper> entry : rootMappers.entrySet()) {
|
||||||
// root mappers included in root object will get merge in the rootObjectMapper
|
// root mappers included in root object will get merge in the rootObjectMapper
|
||||||
if (entry.getValue().includeInObject()) {
|
if (entry.getValue().includeInObject()) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -680,8 +631,6 @@ public class DocumentMapper implements ToXContent {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
@Override public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||||
List<Mapper> additional = new ArrayList<Mapper>();
|
|
||||||
additional.addAll(Arrays.asList(rootMappersNotIncludedInObject));
|
|
||||||
rootObjectMapper.toXContent(builder, params, new ToXContent() {
|
rootObjectMapper.toXContent(builder, params, new ToXContent() {
|
||||||
@Override public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
@Override public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||||
if (indexAnalyzer != null && searchAnalyzer != null && indexAnalyzer.name().equals(searchAnalyzer.name()) && !indexAnalyzer.name().startsWith("_")) {
|
if (indexAnalyzer != null && searchAnalyzer != null && indexAnalyzer.name().equals(searchAnalyzer.name()) && !indexAnalyzer.name().startsWith("_")) {
|
||||||
|
@ -709,7 +658,7 @@ public class DocumentMapper implements ToXContent {
|
||||||
}
|
}
|
||||||
// no need to pass here id and boost, since they are added to the root object mapper
|
// no need to pass here id and boost, since they are added to the root object mapper
|
||||||
// in the constructor
|
// in the constructor
|
||||||
}, additional.toArray(new Mapper[additional.size()]));
|
}, rootMappersNotIncludedInObject);
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,6 @@ import org.elasticsearch.index.settings.IndexSettings;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import static org.elasticsearch.common.xcontent.support.XContentMapValues.*;
|
|
||||||
import static org.elasticsearch.index.mapper.MapperBuilders.*;
|
import static org.elasticsearch.index.mapper.MapperBuilders.*;
|
||||||
import static org.elasticsearch.index.mapper.core.TypeParsers.*;
|
import static org.elasticsearch.index.mapper.core.TypeParsers.*;
|
||||||
|
|
||||||
|
@ -95,6 +94,9 @@ public class DocumentMapperParser extends AbstractIndexComponent {
|
||||||
.put(TypeFieldMapper.NAME, new TypeFieldMapper.TypeParser())
|
.put(TypeFieldMapper.NAME, new TypeFieldMapper.TypeParser())
|
||||||
.put(AllFieldMapper.NAME, new AllFieldMapper.TypeParser())
|
.put(AllFieldMapper.NAME, new AllFieldMapper.TypeParser())
|
||||||
.put(AnalyzerMapper.NAME, new AnalyzerMapper.TypeParser())
|
.put(AnalyzerMapper.NAME, new AnalyzerMapper.TypeParser())
|
||||||
|
.put(BoostFieldMapper.NAME, new BoostFieldMapper.TypeParser())
|
||||||
|
.put(ParentFieldMapper.NAME, new ParentFieldMapper.TypeParser())
|
||||||
|
.put(RoutingFieldMapper.NAME, new RoutingFieldMapper.TypeParser())
|
||||||
.immutableMap();
|
.immutableMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,12 +165,6 @@ public class DocumentMapperParser extends AbstractIndexComponent {
|
||||||
docBuilder.idField(parseIdField((Map<String, Object>) fieldNode, parserContext));
|
docBuilder.idField(parseIdField((Map<String, Object>) fieldNode, parserContext));
|
||||||
} else if (UidFieldMapper.CONTENT_TYPE.equals(fieldName) || "uidField".equals(fieldName)) {
|
} else if (UidFieldMapper.CONTENT_TYPE.equals(fieldName) || "uidField".equals(fieldName)) {
|
||||||
docBuilder.uidField(parseUidField((Map<String, Object>) fieldNode, parserContext));
|
docBuilder.uidField(parseUidField((Map<String, Object>) fieldNode, parserContext));
|
||||||
} else if (RoutingFieldMapper.CONTENT_TYPE.equals(fieldName)) {
|
|
||||||
docBuilder.routingField(parseRoutingField((Map<String, Object>) fieldNode, parserContext));
|
|
||||||
} else if (ParentFieldMapper.CONTENT_TYPE.equals(fieldName)) {
|
|
||||||
docBuilder.parentFiled(parseParentField((Map<String, Object>) fieldNode, parserContext));
|
|
||||||
} else if (BoostFieldMapper.CONTENT_TYPE.equals(fieldName) || "boostField".equals(fieldName)) {
|
|
||||||
docBuilder.boostField(parseBoostField((Map<String, Object>) fieldNode, parserContext));
|
|
||||||
} else if ("index_analyzer".equals(fieldName)) {
|
} else if ("index_analyzer".equals(fieldName)) {
|
||||||
docBuilder.indexAnalyzer(analysisService.analyzer(fieldNode.toString()));
|
docBuilder.indexAnalyzer(analysisService.analyzer(fieldNode.toString()));
|
||||||
} else if ("search_analyzer".equals(fieldName)) {
|
} else if ("search_analyzer".equals(fieldName)) {
|
||||||
|
@ -208,54 +204,12 @@ public class DocumentMapperParser extends AbstractIndexComponent {
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
private BoostFieldMapper.Builder parseBoostField(Map<String, Object> boostNode, Mapper.TypeParser.ParserContext parserContext) {
|
|
||||||
String name = boostNode.get("name") == null ? BoostFieldMapper.Defaults.NAME : boostNode.get("name").toString();
|
|
||||||
BoostFieldMapper.Builder builder = boost(name);
|
|
||||||
parseNumberField(builder, name, boostNode, parserContext);
|
|
||||||
for (Map.Entry<String, Object> entry : boostNode.entrySet()) {
|
|
||||||
String propName = Strings.toUnderscoreCase(entry.getKey());
|
|
||||||
Object propNode = entry.getValue();
|
|
||||||
if (propName.equals("null_value")) {
|
|
||||||
builder.nullValue(nodeFloatValue(propNode));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return builder;
|
|
||||||
}
|
|
||||||
|
|
||||||
private IdFieldMapper.Builder parseIdField(Map<String, Object> idNode, Mapper.TypeParser.ParserContext parserContext) {
|
private IdFieldMapper.Builder parseIdField(Map<String, Object> idNode, Mapper.TypeParser.ParserContext parserContext) {
|
||||||
IdFieldMapper.Builder builder = id();
|
IdFieldMapper.Builder builder = id();
|
||||||
parseField(builder, builder.name, idNode, parserContext);
|
parseField(builder, builder.name, idNode, parserContext);
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE, we also parse this in MappingMetaData
|
|
||||||
private RoutingFieldMapper.Builder parseRoutingField(Map<String, Object> routingNode, Mapper.TypeParser.ParserContext parserContext) {
|
|
||||||
RoutingFieldMapper.Builder builder = routing();
|
|
||||||
parseField(builder, builder.name, routingNode, parserContext);
|
|
||||||
for (Map.Entry<String, Object> entry : routingNode.entrySet()) {
|
|
||||||
String fieldName = Strings.toUnderscoreCase(entry.getKey());
|
|
||||||
Object fieldNode = entry.getValue();
|
|
||||||
if (fieldName.equals("required")) {
|
|
||||||
builder.required(nodeBooleanValue(fieldNode));
|
|
||||||
} else if (fieldName.equals("path")) {
|
|
||||||
builder.path(fieldNode.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return builder;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ParentFieldMapper.Builder parseParentField(Map<String, Object> parentNode, Mapper.TypeParser.ParserContext parserContext) {
|
|
||||||
ParentFieldMapper.Builder builder = new ParentFieldMapper.Builder();
|
|
||||||
for (Map.Entry<String, Object> entry : parentNode.entrySet()) {
|
|
||||||
String fieldName = Strings.toUnderscoreCase(entry.getKey());
|
|
||||||
Object fieldNode = entry.getValue();
|
|
||||||
if (fieldName.equals("type")) {
|
|
||||||
builder.type(fieldNode.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return builder;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings({"unchecked"})
|
@SuppressWarnings({"unchecked"})
|
||||||
private Tuple<String, Map<String, Object>> extractMapping(String type, String source) throws MapperParsingException {
|
private Tuple<String, Map<String, Object>> extractMapping(String type, String source) throws MapperParsingException {
|
||||||
Map<String, Object> root;
|
Map<String, Object> root;
|
||||||
|
|
|
@ -27,6 +27,7 @@ import org.apache.lucene.search.NumericRangeQuery;
|
||||||
import org.apache.lucene.search.Query;
|
import org.apache.lucene.search.Query;
|
||||||
import org.apache.lucene.util.NumericUtils;
|
import org.apache.lucene.util.NumericUtils;
|
||||||
import org.elasticsearch.common.Numbers;
|
import org.elasticsearch.common.Numbers;
|
||||||
|
import org.elasticsearch.common.Strings;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
import org.elasticsearch.index.analysis.NamedAnalyzer;
|
import org.elasticsearch.index.analysis.NamedAnalyzer;
|
||||||
|
@ -35,21 +36,29 @@ import org.elasticsearch.index.cache.field.data.FieldDataCache;
|
||||||
import org.elasticsearch.index.field.data.FieldDataType;
|
import org.elasticsearch.index.field.data.FieldDataType;
|
||||||
import org.elasticsearch.index.mapper.InternalMapper;
|
import org.elasticsearch.index.mapper.InternalMapper;
|
||||||
import org.elasticsearch.index.mapper.Mapper;
|
import org.elasticsearch.index.mapper.Mapper;
|
||||||
|
import org.elasticsearch.index.mapper.MapperBuilders;
|
||||||
|
import org.elasticsearch.index.mapper.MapperParsingException;
|
||||||
import org.elasticsearch.index.mapper.MergeContext;
|
import org.elasticsearch.index.mapper.MergeContext;
|
||||||
import org.elasticsearch.index.mapper.MergeMappingException;
|
import org.elasticsearch.index.mapper.MergeMappingException;
|
||||||
import org.elasticsearch.index.mapper.ParseContext;
|
import org.elasticsearch.index.mapper.ParseContext;
|
||||||
|
import org.elasticsearch.index.mapper.RootMapper;
|
||||||
import org.elasticsearch.index.mapper.core.FloatFieldMapper;
|
import org.elasticsearch.index.mapper.core.FloatFieldMapper;
|
||||||
import org.elasticsearch.index.mapper.core.NumberFieldMapper;
|
import org.elasticsearch.index.mapper.core.NumberFieldMapper;
|
||||||
import org.elasticsearch.index.search.NumericRangeFieldDataFilter;
|
import org.elasticsearch.index.search.NumericRangeFieldDataFilter;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static org.elasticsearch.common.xcontent.support.XContentMapValues.*;
|
||||||
|
import static org.elasticsearch.index.mapper.core.TypeParsers.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author kimchy (shay.banon)
|
* @author kimchy (shay.banon)
|
||||||
*/
|
*/
|
||||||
public class BoostFieldMapper extends NumberFieldMapper<Float> implements InternalMapper {
|
public class BoostFieldMapper extends NumberFieldMapper<Float> implements InternalMapper, RootMapper {
|
||||||
|
|
||||||
public static final String CONTENT_TYPE = "_boost";
|
public static final String CONTENT_TYPE = "_boost";
|
||||||
|
public static final String NAME = "_boost";
|
||||||
|
|
||||||
public static class Defaults extends NumberFieldMapper.Defaults {
|
public static class Defaults extends NumberFieldMapper.Defaults {
|
||||||
public static final String NAME = "_boost";
|
public static final String NAME = "_boost";
|
||||||
|
@ -80,6 +89,21 @@ public class BoostFieldMapper extends NumberFieldMapper<Float> implements Intern
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class TypeParser implements Mapper.TypeParser {
|
||||||
|
@Override public Mapper.Builder parse(String fieldName, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
|
||||||
|
String name = node.get("name") == null ? BoostFieldMapper.Defaults.NAME : node.get("name").toString();
|
||||||
|
BoostFieldMapper.Builder builder = MapperBuilders.boost(name);
|
||||||
|
parseNumberField(builder, name, node, parserContext);
|
||||||
|
for (Map.Entry<String, Object> entry : node.entrySet()) {
|
||||||
|
String propName = Strings.toUnderscoreCase(entry.getKey());
|
||||||
|
Object propNode = entry.getValue();
|
||||||
|
if (propName.equals("null_value")) {
|
||||||
|
builder.nullValue(nodeFloatValue(propNode));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private final Float nullValue;
|
private final Float nullValue;
|
||||||
|
|
||||||
|
@ -160,6 +184,19 @@ public class BoostFieldMapper extends NumberFieldMapper<Float> implements Intern
|
||||||
includeLower, includeUpper);
|
includeLower, includeUpper);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override public void preParse(ParseContext context) throws IOException {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public void postParse(ParseContext context) throws IOException {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public void validate(ParseContext context) throws MapperParsingException {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public boolean includeInObject() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override public void parse(ParseContext context) throws IOException {
|
@Override public void parse(ParseContext context) throws IOException {
|
||||||
// we override parse since we want to handle cases where it is not indexed and not stored (the default)
|
// we override parse since we want to handle cases where it is not indexed and not stored (the default)
|
||||||
float value = parseFloatValue(context);
|
float value = parseFloatValue(context);
|
||||||
|
|
|
@ -22,6 +22,7 @@ package org.elasticsearch.index.mapper.internal;
|
||||||
import org.apache.lucene.document.Field;
|
import org.apache.lucene.document.Field;
|
||||||
import org.apache.lucene.document.Fieldable;
|
import org.apache.lucene.document.Fieldable;
|
||||||
import org.apache.lucene.index.Term;
|
import org.apache.lucene.index.Term;
|
||||||
|
import org.elasticsearch.common.Strings;
|
||||||
import org.elasticsearch.common.lucene.Lucene;
|
import org.elasticsearch.common.lucene.Lucene;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.index.mapper.InternalMapper;
|
import org.elasticsearch.index.mapper.InternalMapper;
|
||||||
|
@ -30,15 +31,17 @@ import org.elasticsearch.index.mapper.MapperParsingException;
|
||||||
import org.elasticsearch.index.mapper.MergeContext;
|
import org.elasticsearch.index.mapper.MergeContext;
|
||||||
import org.elasticsearch.index.mapper.MergeMappingException;
|
import org.elasticsearch.index.mapper.MergeMappingException;
|
||||||
import org.elasticsearch.index.mapper.ParseContext;
|
import org.elasticsearch.index.mapper.ParseContext;
|
||||||
|
import org.elasticsearch.index.mapper.RootMapper;
|
||||||
import org.elasticsearch.index.mapper.Uid;
|
import org.elasticsearch.index.mapper.Uid;
|
||||||
import org.elasticsearch.index.mapper.core.AbstractFieldMapper;
|
import org.elasticsearch.index.mapper.core.AbstractFieldMapper;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author kimchy (shay.banon)
|
* @author kimchy (shay.banon)
|
||||||
*/
|
*/
|
||||||
public class ParentFieldMapper extends AbstractFieldMapper<Uid> implements InternalMapper {
|
public class ParentFieldMapper extends AbstractFieldMapper<Uid> implements InternalMapper, RootMapper {
|
||||||
|
|
||||||
public static final String NAME = "_parent";
|
public static final String NAME = "_parent";
|
||||||
|
|
||||||
|
@ -75,6 +78,20 @@ public class ParentFieldMapper extends AbstractFieldMapper<Uid> implements Inter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class TypeParser implements Mapper.TypeParser {
|
||||||
|
@Override public Mapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
|
||||||
|
ParentFieldMapper.Builder builder = new ParentFieldMapper.Builder();
|
||||||
|
for (Map.Entry<String, Object> entry : node.entrySet()) {
|
||||||
|
String fieldName = Strings.toUnderscoreCase(entry.getKey());
|
||||||
|
Object fieldNode = entry.getValue();
|
||||||
|
if (fieldName.equals("type")) {
|
||||||
|
builder.type(fieldNode.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private final String type;
|
private final String type;
|
||||||
|
|
||||||
protected ParentFieldMapper(String name, String indexName, String type) {
|
protected ParentFieldMapper(String name, String indexName, String type) {
|
||||||
|
@ -87,6 +104,20 @@ public class ParentFieldMapper extends AbstractFieldMapper<Uid> implements Inter
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override public void preParse(ParseContext context) throws IOException {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public void postParse(ParseContext context) throws IOException {
|
||||||
|
parse(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public void validate(ParseContext context) throws MapperParsingException {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public boolean includeInObject() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override protected Field parseCreateField(ParseContext context) throws IOException {
|
@Override protected Field parseCreateField(ParseContext context) throws IOException {
|
||||||
if (context.parser().currentName() != null && context.parser().currentName().equals(Defaults.NAME)) {
|
if (context.parser().currentName() != null && context.parser().currentName().equals(Defaults.NAME)) {
|
||||||
// we are in the parsing of _parent phase
|
// we are in the parsing of _parent phase
|
||||||
|
|
|
@ -22,6 +22,7 @@ package org.elasticsearch.index.mapper.internal;
|
||||||
import org.apache.lucene.document.Document;
|
import org.apache.lucene.document.Document;
|
||||||
import org.apache.lucene.document.Field;
|
import org.apache.lucene.document.Field;
|
||||||
import org.apache.lucene.document.Fieldable;
|
import org.apache.lucene.document.Fieldable;
|
||||||
|
import org.elasticsearch.common.Strings;
|
||||||
import org.elasticsearch.common.lucene.Lucene;
|
import org.elasticsearch.common.lucene.Lucene;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.index.mapper.InternalMapper;
|
import org.elasticsearch.index.mapper.InternalMapper;
|
||||||
|
@ -30,15 +31,22 @@ import org.elasticsearch.index.mapper.MapperParsingException;
|
||||||
import org.elasticsearch.index.mapper.MergeContext;
|
import org.elasticsearch.index.mapper.MergeContext;
|
||||||
import org.elasticsearch.index.mapper.MergeMappingException;
|
import org.elasticsearch.index.mapper.MergeMappingException;
|
||||||
import org.elasticsearch.index.mapper.ParseContext;
|
import org.elasticsearch.index.mapper.ParseContext;
|
||||||
|
import org.elasticsearch.index.mapper.RootMapper;
|
||||||
import org.elasticsearch.index.mapper.core.AbstractFieldMapper;
|
import org.elasticsearch.index.mapper.core.AbstractFieldMapper;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static org.elasticsearch.common.xcontent.support.XContentMapValues.*;
|
||||||
|
import static org.elasticsearch.index.mapper.MapperBuilders.*;
|
||||||
|
import static org.elasticsearch.index.mapper.core.TypeParsers.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author kimchy (shay.banon)
|
* @author kimchy (shay.banon)
|
||||||
*/
|
*/
|
||||||
public class RoutingFieldMapper extends AbstractFieldMapper<String> implements InternalMapper {
|
public class RoutingFieldMapper extends AbstractFieldMapper<String> implements InternalMapper, RootMapper {
|
||||||
|
|
||||||
|
public static final String NAME = "_routing";
|
||||||
public static final String CONTENT_TYPE = "_routing";
|
public static final String CONTENT_TYPE = "_routing";
|
||||||
|
|
||||||
public static class Defaults extends AbstractFieldMapper.Defaults {
|
public static class Defaults extends AbstractFieldMapper.Defaults {
|
||||||
|
@ -78,6 +86,24 @@ public class RoutingFieldMapper extends AbstractFieldMapper<String> implements I
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class TypeParser implements Mapper.TypeParser {
|
||||||
|
@Override public Mapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
|
||||||
|
RoutingFieldMapper.Builder builder = routing();
|
||||||
|
parseField(builder, builder.name, node, parserContext);
|
||||||
|
for (Map.Entry<String, Object> entry : node.entrySet()) {
|
||||||
|
String fieldName = Strings.toUnderscoreCase(entry.getKey());
|
||||||
|
Object fieldNode = entry.getValue();
|
||||||
|
if (fieldName.equals("required")) {
|
||||||
|
builder.required(nodeBooleanValue(fieldNode));
|
||||||
|
} else if (fieldName.equals("path")) {
|
||||||
|
builder.path(fieldNode.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private boolean required;
|
private boolean required;
|
||||||
|
|
||||||
private final String path;
|
private final String path;
|
||||||
|
@ -126,7 +152,7 @@ public class RoutingFieldMapper extends AbstractFieldMapper<String> implements I
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void validate(ParseContext context) throws MapperParsingException {
|
@Override public void validate(ParseContext context) throws MapperParsingException {
|
||||||
String routing = context.sourceToParse().routing();
|
String routing = context.sourceToParse().routing();
|
||||||
if (path != null && routing != null) {
|
if (path != null && routing != null) {
|
||||||
// we have a path, check if we can validate we have the same routing value as the one in the doc...
|
// we have a path, check if we can validate we have the same routing value as the one in the doc...
|
||||||
|
@ -140,9 +166,26 @@ public class RoutingFieldMapper extends AbstractFieldMapper<String> implements I
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override public void preParse(ParseContext context) throws IOException {
|
||||||
|
super.parse(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public void postParse(ParseContext context) throws IOException {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public void parse(ParseContext context) throws IOException {
|
||||||
|
// no need ot parse here, we either get the routing in the sourceToParse
|
||||||
|
// or we don't have routing, if we get it in sourceToParse, we process it in preParse
|
||||||
|
// which will always be called
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public boolean includeInObject() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override protected Field parseCreateField(ParseContext context) throws IOException {
|
@Override protected Field parseCreateField(ParseContext context) throws IOException {
|
||||||
if (context.externalValueSet()) {
|
if (context.sourceToParse().routing() != null) {
|
||||||
String routing = (String) context.externalValue();
|
String routing = context.sourceToParse().routing();
|
||||||
if (routing != null) {
|
if (routing != null) {
|
||||||
if (!indexed() && !stored()) {
|
if (!indexed() && !stored()) {
|
||||||
context.ignoredValue(names.indexName(), routing);
|
context.ignoredValue(names.indexName(), routing);
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
/*
|
||||||
|
* 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.boost;
|
||||||
|
|
||||||
|
import org.elasticsearch.common.xcontent.XContentFactory;
|
||||||
|
import org.elasticsearch.index.mapper.DocumentMapper;
|
||||||
|
import org.elasticsearch.index.mapper.MapperTests;
|
||||||
|
import org.elasticsearch.index.mapper.ParsedDocument;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.*;
|
||||||
|
import static org.hamcrest.Matchers.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public class BoostMappingTests {
|
||||||
|
|
||||||
|
@Test public void testDefaultMapping() throws Exception {
|
||||||
|
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type").endObject().endObject().string();
|
||||||
|
|
||||||
|
DocumentMapper mapper = MapperTests.newParser().parse(mapping);
|
||||||
|
|
||||||
|
ParsedDocument doc = mapper.parse("type", "1", XContentFactory.jsonBuilder().startObject()
|
||||||
|
.field("_boost", 2.0f)
|
||||||
|
.endObject().copiedBytes());
|
||||||
|
assertThat(doc.rootDoc().getBoost(), equalTo(2.0f));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test public void testCustomName() throws Exception {
|
||||||
|
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
|
||||||
|
.startObject("_boost").field("name", "custom_boost").endObject()
|
||||||
|
.endObject().endObject().string();
|
||||||
|
|
||||||
|
DocumentMapper mapper = MapperTests.newParser().parse(mapping);
|
||||||
|
|
||||||
|
ParsedDocument doc = mapper.parse("type", "1", XContentFactory.jsonBuilder().startObject()
|
||||||
|
.field("_boost", 2.0f)
|
||||||
|
.endObject().copiedBytes());
|
||||||
|
assertThat(doc.rootDoc().getBoost(), equalTo(1.0f));
|
||||||
|
|
||||||
|
doc = mapper.parse("type", "1", XContentFactory.jsonBuilder().startObject()
|
||||||
|
.field("custom_boost", 2.0f)
|
||||||
|
.endObject().copiedBytes());
|
||||||
|
assertThat(doc.rootDoc().getBoost(), equalTo(2.0f));
|
||||||
|
}
|
||||||
|
}
|
|
@ -40,7 +40,7 @@ public class IndexTypeMapperTests {
|
||||||
.startObject("_index").field("enabled", true).field("store", "yes").endObject()
|
.startObject("_index").field("enabled", true).field("store", "yes").endObject()
|
||||||
.endObject().endObject().string();
|
.endObject().endObject().string();
|
||||||
DocumentMapper docMapper = MapperTests.newParser().parse(mapping);
|
DocumentMapper docMapper = MapperTests.newParser().parse(mapping);
|
||||||
IndexFieldMapper indexMapper = docMapper.rootMapper(IndexFieldMapper.NAME);
|
IndexFieldMapper indexMapper = docMapper.rootMapper(IndexFieldMapper.class);
|
||||||
assertThat(indexMapper.enabled(), equalTo(true));
|
assertThat(indexMapper.enabled(), equalTo(true));
|
||||||
assertThat(indexMapper.store(), equalTo(Field.Store.YES));
|
assertThat(indexMapper.store(), equalTo(Field.Store.YES));
|
||||||
assertThat(docMapper.mappers().indexName("_index").mapper(), instanceOf(IndexFieldMapper.class));
|
assertThat(docMapper.mappers().indexName("_index").mapper(), instanceOf(IndexFieldMapper.class));
|
||||||
|
@ -60,7 +60,7 @@ public class IndexTypeMapperTests {
|
||||||
.startObject("_index").field("enabled", false).field("store", "yes").endObject()
|
.startObject("_index").field("enabled", false).field("store", "yes").endObject()
|
||||||
.endObject().endObject().string();
|
.endObject().endObject().string();
|
||||||
DocumentMapper docMapper = MapperTests.newParser().parse(mapping);
|
DocumentMapper docMapper = MapperTests.newParser().parse(mapping);
|
||||||
IndexFieldMapper indexMapper = docMapper.rootMapper(IndexFieldMapper.NAME);
|
IndexFieldMapper indexMapper = docMapper.rootMapper(IndexFieldMapper.class);
|
||||||
assertThat(indexMapper.enabled(), equalTo(false));
|
assertThat(indexMapper.enabled(), equalTo(false));
|
||||||
assertThat(indexMapper.store(), equalTo(Field.Store.YES));
|
assertThat(indexMapper.store(), equalTo(Field.Store.YES));
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ public class IndexTypeMapperTests {
|
||||||
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
|
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
|
||||||
.endObject().endObject().string();
|
.endObject().endObject().string();
|
||||||
DocumentMapper docMapper = MapperTests.newParser().parse(mapping);
|
DocumentMapper docMapper = MapperTests.newParser().parse(mapping);
|
||||||
IndexFieldMapper indexMapper = docMapper.rootMapper(IndexFieldMapper.NAME);
|
IndexFieldMapper indexMapper = docMapper.rootMapper(IndexFieldMapper.class);
|
||||||
assertThat(indexMapper.enabled(), equalTo(false));
|
assertThat(indexMapper.enabled(), equalTo(false));
|
||||||
assertThat(indexMapper.store(), equalTo(Field.Store.NO));
|
assertThat(indexMapper.store(), equalTo(Field.Store.NO));
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,22 @@ import static org.hamcrest.Matchers.*;
|
||||||
*/
|
*/
|
||||||
public class ParentMappingTests {
|
public class ParentMappingTests {
|
||||||
|
|
||||||
|
@Test public void parentNotMapped() throws Exception {
|
||||||
|
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
|
||||||
|
.endObject().endObject().string();
|
||||||
|
DocumentMapper docMapper = MapperTests.newParser().parse(mapping);
|
||||||
|
|
||||||
|
ParsedDocument doc = docMapper.parse(SourceToParse.source(XContentFactory.jsonBuilder()
|
||||||
|
.startObject()
|
||||||
|
.field("_parent", "1122")
|
||||||
|
.field("x_field", "x_value")
|
||||||
|
.endObject()
|
||||||
|
.copiedBytes()).type("type").id("1"));
|
||||||
|
|
||||||
|
// no _parent mapping, used as a simple field
|
||||||
|
assertThat(doc.rootDoc().get("_parent"), equalTo("1122"));
|
||||||
|
}
|
||||||
|
|
||||||
@Test public void parentSetInDocNotExternally() throws Exception {
|
@Test public void parentSetInDocNotExternally() throws Exception {
|
||||||
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
|
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
|
||||||
.startObject("_parent").field("type", "p_type").endObject()
|
.startObject("_parent").field("type", "p_type").endObject()
|
||||||
|
|
Loading…
Reference in New Issue