more refactoring to generalize root level field mappers

This commit is contained in:
Shay Banon 2011-08-18 04:55:57 +03:00
parent 821c3524a2
commit a9bc775213
8 changed files with 230 additions and 136 deletions

View File

@ -48,10 +48,7 @@ import org.elasticsearch.index.mapper.object.ObjectMapper;
import org.elasticsearch.index.mapper.object.RootObjectMapper;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
@ -140,13 +137,7 @@ public class DocumentMapper implements ToXContent {
private IdFieldMapper idFieldMapper = new IdFieldMapper();
private RoutingFieldMapper routingFieldMapper = new RoutingFieldMapper();
private BoostFieldMapper boostFieldMapper = new BoostFieldMapper();
private ParentFieldMapper parentFieldMapper = null;
private Map<String, RootMapper> rootMappers = new HashMap<String, RootMapper>();
private Map<Class<? extends RootMapper>, RootMapper> rootMappers = Maps.newHashMap();
private NamedAnalyzer indexAnalyzer;
@ -170,12 +161,15 @@ public class DocumentMapper implements ToXContent {
}
}
// add default mappers
this.rootMappers.put(SizeFieldMapper.NAME, new SizeFieldMapper());
this.rootMappers.put(IndexFieldMapper.NAME, new IndexFieldMapper());
this.rootMappers.put(SourceFieldMapper.NAME, new SourceFieldMapper());
this.rootMappers.put(TypeFieldMapper.NAME, new TypeFieldMapper());
this.rootMappers.put(AllFieldMapper.NAME, new AllFieldMapper());
this.rootMappers.put(AnalyzerMapper.NAME, new AnalyzerMapper());
this.rootMappers.put(SizeFieldMapper.class, new SizeFieldMapper());
this.rootMappers.put(IndexFieldMapper.class, new IndexFieldMapper());
this.rootMappers.put(SourceFieldMapper.class, new SourceFieldMapper());
this.rootMappers.put(TypeFieldMapper.class, new TypeFieldMapper());
this.rootMappers.put(AllFieldMapper.class, new AllFieldMapper());
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) {
@ -184,7 +178,8 @@ public class DocumentMapper implements ToXContent {
}
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;
}
@ -198,21 +193,6 @@ public class DocumentMapper implements ToXContent {
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) {
this.indexAnalyzer = indexAnalyzer;
return this;
@ -234,7 +214,7 @@ public class DocumentMapper implements ToXContent {
public DocumentMapper build(DocumentMapperParser docMapperParser) {
Preconditions.checkNotNull(rootObjectMapper, "Mapper builder must have the root object mapper set");
return new DocumentMapper(index, docMapperParser, rootObjectMapper, meta, uidFieldMapper, idFieldMapper,
parentFieldMapper, routingFieldMapper, indexAnalyzer, searchAnalyzer, boostFieldMapper,
indexAnalyzer, searchAnalyzer,
rootMappers);
}
}
@ -260,15 +240,9 @@ public class DocumentMapper implements ToXContent {
private final IdFieldMapper idFieldMapper;
private final RoutingFieldMapper routingFieldMapper;
private final ParentFieldMapper parentFieldMapper;
private final BoostFieldMapper boostFieldMapper;
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[] rootMappersNotIncludedInObject;
@ -295,11 +269,8 @@ public class DocumentMapper implements ToXContent {
ImmutableMap<String, Object> meta,
UidFieldMapper uidFieldMapper,
IdFieldMapper idFieldMapper,
@Nullable ParentFieldMapper parentFieldMapper,
RoutingFieldMapper routingFieldMapper,
NamedAnalyzer indexAnalyzer, NamedAnalyzer searchAnalyzer,
@Nullable BoostFieldMapper boostFieldMapper,
Map<String, RootMapper> rootMappers) {
Map<Class<? extends RootMapper>, RootMapper> rootMappers) {
this.index = index;
this.type = rootObjectMapper.name();
this.docMapperParser = docMapperParser;
@ -307,9 +278,6 @@ public class DocumentMapper implements ToXContent {
this.rootObjectMapper = rootObjectMapper;
this.uidFieldMapper = uidFieldMapper;
this.idFieldMapper = idFieldMapper;
this.parentFieldMapper = parentFieldMapper;
this.routingFieldMapper = routingFieldMapper;
this.boostFieldMapper = boostFieldMapper;
this.rootMappers = ImmutableMap.copyOf(rootMappers);
this.rootMappersOrdered = rootMappers.values().toArray(new RootMapper[rootMappers.values().size()]);
@ -327,15 +295,10 @@ public class DocumentMapper implements ToXContent {
this.typeFilter = typeMapper().fieldFilter(type);
rootObjectMapper.putMapper(idFieldMapper);
if (boostFieldMapper != null) {
rootObjectMapper.putMapper(boostFieldMapper);
if (rootMapper(ParentFieldMapper.class) != null) {
// 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();
for (RootMapper rootMapper : rootMappersOrdered) {
@ -395,28 +358,28 @@ public class DocumentMapper implements ToXContent {
return this.uidFieldMapper;
}
@SuppressWarnings({"unchecked"}) public <T extends RootMapper> T rootMapper(String name) {
return (T) rootMappers.get(name);
@SuppressWarnings({"unchecked"}) public <T extends RootMapper> T rootMapper(Class<T> type) {
return (T) rootMappers.get(type);
}
public TypeFieldMapper typeMapper() {
return rootMapper(TypeFieldMapper.NAME);
return rootMapper(TypeFieldMapper.class);
}
public SourceFieldMapper sourceMapper() {
return rootMapper(SourceFieldMapper.NAME);
return rootMapper(SourceFieldMapper.class);
}
public AllFieldMapper allFieldMapper() {
return rootMapper(AllFieldMapper.NAME);
return rootMapper(AllFieldMapper.class);
}
public RoutingFieldMapper routingFieldMapper() {
return this.routingFieldMapper;
return rootMapper(RoutingFieldMapper.class);
}
public ParentFieldMapper parentFieldMapper() {
return this.parentFieldMapper;
return rootMapper(ParentFieldMapper.class);
}
public Analyzer indexAnalyzer() {
@ -515,10 +478,6 @@ public class DocumentMapper implements ToXContent {
context.id(source.id());
uidFieldMapper.parse(context);
}
if (source.routing() != null) {
context.externalValue(source.routing());
routingFieldMapper.parse(context);
}
if (!emptyDoc) {
rootObjectMapper.parse(context);
@ -563,17 +522,9 @@ public class DocumentMapper implements ToXContent {
rootMapper.postParse(context);
}
if (parentFieldMapper != null) {
parentFieldMapper.parse(context);
}
for (RootMapper rootMapper : rootMappersOrdered) {
rootMapper.validate(context);
}
// validate aggregated mappers (TODO: need to be added as a phase to any field mapper)
routingFieldMapper.validate(context);
} catch (IOException e) {
throw new MapperParsingException("Failed to parse", e);
} finally {
@ -638,7 +589,7 @@ public class DocumentMapper implements ToXContent {
MergeContext mergeContext = new MergeContext(this, mergeFlags);
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
if (entry.getValue().includeInObject()) {
continue;
@ -680,8 +631,6 @@ public class DocumentMapper implements ToXContent {
}
@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() {
@Override public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
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
// in the constructor
}, additional.toArray(new Mapper[additional.size()]));
}, rootMappersNotIncludedInObject);
return builder;
}
}

View File

@ -45,7 +45,6 @@ import org.elasticsearch.index.settings.IndexSettings;
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.*;
@ -95,6 +94,9 @@ public class DocumentMapperParser extends AbstractIndexComponent {
.put(TypeFieldMapper.NAME, new TypeFieldMapper.TypeParser())
.put(AllFieldMapper.NAME, new AllFieldMapper.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();
}
@ -163,12 +165,6 @@ public class DocumentMapperParser extends AbstractIndexComponent {
docBuilder.idField(parseIdField((Map<String, Object>) fieldNode, parserContext));
} else if (UidFieldMapper.CONTENT_TYPE.equals(fieldName) || "uidField".equals(fieldName)) {
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)) {
docBuilder.indexAnalyzer(analysisService.analyzer(fieldNode.toString()));
} else if ("search_analyzer".equals(fieldName)) {
@ -208,54 +204,12 @@ public class DocumentMapperParser extends AbstractIndexComponent {
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) {
IdFieldMapper.Builder builder = id();
parseField(builder, builder.name, idNode, parserContext);
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"})
private Tuple<String, Map<String, Object>> extractMapping(String type, String source) throws MapperParsingException {
Map<String, Object> root;

View File

@ -27,6 +27,7 @@ import org.apache.lucene.search.NumericRangeQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.util.NumericUtils;
import org.elasticsearch.common.Numbers;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
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.mapper.InternalMapper;
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.MergeMappingException;
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.NumberFieldMapper;
import org.elasticsearch.index.search.NumericRangeFieldDataFilter;
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)
*/
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 NAME = "_boost";
public static class Defaults extends NumberFieldMapper.Defaults {
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;
@ -160,6 +184,19 @@ public class BoostFieldMapper extends NumberFieldMapper<Float> implements Intern
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 {
// we override parse since we want to handle cases where it is not indexed and not stored (the default)
float value = parseFloatValue(context);

View File

@ -22,6 +22,7 @@ package org.elasticsearch.index.mapper.internal;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.Fieldable;
import org.apache.lucene.index.Term;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.lucene.Lucene;
import org.elasticsearch.common.xcontent.XContentBuilder;
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.MergeMappingException;
import org.elasticsearch.index.mapper.ParseContext;
import org.elasticsearch.index.mapper.RootMapper;
import org.elasticsearch.index.mapper.Uid;
import org.elasticsearch.index.mapper.core.AbstractFieldMapper;
import java.io.IOException;
import java.util.Map;
/**
* @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";
@ -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;
protected ParentFieldMapper(String name, String indexName, String type) {
@ -87,6 +104,20 @@ public class ParentFieldMapper extends AbstractFieldMapper<Uid> implements Inter
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 {
if (context.parser().currentName() != null && context.parser().currentName().equals(Defaults.NAME)) {
// we are in the parsing of _parent phase

View File

@ -22,6 +22,7 @@ package org.elasticsearch.index.mapper.internal;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.Fieldable;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.lucene.Lucene;
import org.elasticsearch.common.xcontent.XContentBuilder;
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.MergeMappingException;
import org.elasticsearch.index.mapper.ParseContext;
import org.elasticsearch.index.mapper.RootMapper;
import org.elasticsearch.index.mapper.core.AbstractFieldMapper;
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)
*/
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 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 final String path;
@ -126,7 +152,7 @@ public class RoutingFieldMapper extends AbstractFieldMapper<String> implements I
return value;
}
public void validate(ParseContext context) throws MapperParsingException {
@Override public void validate(ParseContext context) throws MapperParsingException {
String routing = context.sourceToParse().routing();
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...
@ -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 {
if (context.externalValueSet()) {
String routing = (String) context.externalValue();
if (context.sourceToParse().routing() != null) {
String routing = context.sourceToParse().routing();
if (routing != null) {
if (!indexed() && !stored()) {
context.ignoredValue(names.indexName(), routing);

View File

@ -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));
}
}

View File

@ -40,7 +40,7 @@ public class IndexTypeMapperTests {
.startObject("_index").field("enabled", true).field("store", "yes").endObject()
.endObject().endObject().string();
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.store(), equalTo(Field.Store.YES));
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()
.endObject().endObject().string();
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.store(), equalTo(Field.Store.YES));
@ -78,7 +78,7 @@ public class IndexTypeMapperTests {
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
.endObject().endObject().string();
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.store(), equalTo(Field.Store.NO));

View File

@ -35,6 +35,22 @@ import static org.hamcrest.Matchers.*;
*/
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 {
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
.startObject("_parent").field("type", "p_type").endObject()