diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/index/mapper/DocumentMapper.java b/modules/elasticsearch/src/main/java/org/elasticsearch/index/mapper/DocumentMapper.java index e9712f2cca1..24b4e187897 100644 --- a/modules/elasticsearch/src/main/java/org/elasticsearch/index/mapper/DocumentMapper.java +++ b/modules/elasticsearch/src/main/java/org/elasticsearch/index/mapper/DocumentMapper.java @@ -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 rootMappers = new HashMap(); + private Map, 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 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 rootMappers; + private final ImmutableMap, RootMapper> rootMappers; private final RootMapper[] rootMappersOrdered; private final RootMapper[] rootMappersNotIncludedInObject; @@ -295,11 +269,8 @@ public class DocumentMapper implements ToXContent { ImmutableMap meta, UidFieldMapper uidFieldMapper, IdFieldMapper idFieldMapper, - @Nullable ParentFieldMapper parentFieldMapper, - RoutingFieldMapper routingFieldMapper, NamedAnalyzer indexAnalyzer, NamedAnalyzer searchAnalyzer, - @Nullable BoostFieldMapper boostFieldMapper, - Map rootMappers) { + Map, 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 tempFieldMappers = newArrayList(); for (RootMapper rootMapper : rootMappersOrdered) { @@ -395,28 +358,28 @@ public class DocumentMapper implements ToXContent { return this.uidFieldMapper; } - @SuppressWarnings({"unchecked"}) public T rootMapper(String name) { - return (T) rootMappers.get(name); + @SuppressWarnings({"unchecked"}) public T rootMapper(Class 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 entry : rootMappers.entrySet()) { + for (Map.Entry, 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 additional = new ArrayList(); - 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; } } diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/index/mapper/DocumentMapperParser.java b/modules/elasticsearch/src/main/java/org/elasticsearch/index/mapper/DocumentMapperParser.java index 865f3cabec5..9eea74057d4 100644 --- a/modules/elasticsearch/src/main/java/org/elasticsearch/index/mapper/DocumentMapperParser.java +++ b/modules/elasticsearch/src/main/java/org/elasticsearch/index/mapper/DocumentMapperParser.java @@ -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) fieldNode, parserContext)); } else if (UidFieldMapper.CONTENT_TYPE.equals(fieldName) || "uidField".equals(fieldName)) { docBuilder.uidField(parseUidField((Map) fieldNode, parserContext)); - } else if (RoutingFieldMapper.CONTENT_TYPE.equals(fieldName)) { - docBuilder.routingField(parseRoutingField((Map) fieldNode, parserContext)); - } else if (ParentFieldMapper.CONTENT_TYPE.equals(fieldName)) { - docBuilder.parentFiled(parseParentField((Map) fieldNode, parserContext)); - } else if (BoostFieldMapper.CONTENT_TYPE.equals(fieldName) || "boostField".equals(fieldName)) { - docBuilder.boostField(parseBoostField((Map) 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 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 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 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 routingNode, Mapper.TypeParser.ParserContext parserContext) { - RoutingFieldMapper.Builder builder = routing(); - parseField(builder, builder.name, routingNode, parserContext); - for (Map.Entry 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 parentNode, Mapper.TypeParser.ParserContext parserContext) { - ParentFieldMapper.Builder builder = new ParentFieldMapper.Builder(); - for (Map.Entry 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> extractMapping(String type, String source) throws MapperParsingException { Map root; diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/index/mapper/internal/BoostFieldMapper.java b/modules/elasticsearch/src/main/java/org/elasticsearch/index/mapper/internal/BoostFieldMapper.java index 329ea79a062..01934cf8681 100644 --- a/modules/elasticsearch/src/main/java/org/elasticsearch/index/mapper/internal/BoostFieldMapper.java +++ b/modules/elasticsearch/src/main/java/org/elasticsearch/index/mapper/internal/BoostFieldMapper.java @@ -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 implements InternalMapper { +public class BoostFieldMapper extends NumberFieldMapper 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 implements Intern } } + public static class TypeParser implements Mapper.TypeParser { + @Override public Mapper.Builder parse(String fieldName, Map 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 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 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); diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/index/mapper/internal/ParentFieldMapper.java b/modules/elasticsearch/src/main/java/org/elasticsearch/index/mapper/internal/ParentFieldMapper.java index 50c816822fb..1efcb38e0c3 100644 --- a/modules/elasticsearch/src/main/java/org/elasticsearch/index/mapper/internal/ParentFieldMapper.java +++ b/modules/elasticsearch/src/main/java/org/elasticsearch/index/mapper/internal/ParentFieldMapper.java @@ -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 implements InternalMapper { +public class ParentFieldMapper extends AbstractFieldMapper implements InternalMapper, RootMapper { public static final String NAME = "_parent"; @@ -75,6 +78,20 @@ public class ParentFieldMapper extends AbstractFieldMapper implements Inter } } + public static class TypeParser implements Mapper.TypeParser { + @Override public Mapper.Builder parse(String name, Map node, ParserContext parserContext) throws MapperParsingException { + ParentFieldMapper.Builder builder = new ParentFieldMapper.Builder(); + for (Map.Entry 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 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 diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/index/mapper/internal/RoutingFieldMapper.java b/modules/elasticsearch/src/main/java/org/elasticsearch/index/mapper/internal/RoutingFieldMapper.java index 7eea51637f5..420463fc2a3 100644 --- a/modules/elasticsearch/src/main/java/org/elasticsearch/index/mapper/internal/RoutingFieldMapper.java +++ b/modules/elasticsearch/src/main/java/org/elasticsearch/index/mapper/internal/RoutingFieldMapper.java @@ -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 implements InternalMapper { +public class RoutingFieldMapper extends AbstractFieldMapper 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 implements I } } + public static class TypeParser implements Mapper.TypeParser { + @Override public Mapper.Builder parse(String name, Map node, ParserContext parserContext) throws MapperParsingException { + RoutingFieldMapper.Builder builder = routing(); + parseField(builder, builder.name, node, parserContext); + for (Map.Entry 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 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 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); diff --git a/modules/elasticsearch/src/test/java/org/elasticsearch/index/mapper/boost/BoostMappingTests.java b/modules/elasticsearch/src/test/java/org/elasticsearch/index/mapper/boost/BoostMappingTests.java new file mode 100644 index 00000000000..29391280eb5 --- /dev/null +++ b/modules/elasticsearch/src/test/java/org/elasticsearch/index/mapper/boost/BoostMappingTests.java @@ -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)); + } +} diff --git a/modules/elasticsearch/src/test/java/org/elasticsearch/index/mapper/index/IndexTypeMapperTests.java b/modules/elasticsearch/src/test/java/org/elasticsearch/index/mapper/index/IndexTypeMapperTests.java index 8d0e429c722..da8c958df09 100644 --- a/modules/elasticsearch/src/test/java/org/elasticsearch/index/mapper/index/IndexTypeMapperTests.java +++ b/modules/elasticsearch/src/test/java/org/elasticsearch/index/mapper/index/IndexTypeMapperTests.java @@ -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)); diff --git a/modules/elasticsearch/src/test/java/org/elasticsearch/index/mapper/parent/ParentMappingTests.java b/modules/elasticsearch/src/test/java/org/elasticsearch/index/mapper/parent/ParentMappingTests.java index 33a3a7da206..87dfc10af7f 100644 --- a/modules/elasticsearch/src/test/java/org/elasticsearch/index/mapper/parent/ParentMappingTests.java +++ b/modules/elasticsearch/src/test/java/org/elasticsearch/index/mapper/parent/ParentMappingTests.java @@ -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()