From 972afe61a0958d0c49b6910288ff88f8ca493662 Mon Sep 17 00:00:00 2001 From: Colin Goodheart-Smithe Date: Wed, 20 Aug 2014 16:20:36 +0100 Subject: [PATCH] Mappers: Better validation of mapping JSON Closes #7205 --- .../index/mapper/DocumentMapperParser.java | 72 ++++++++++++---- .../index/mapper/core/BinaryFieldMapper.java | 6 +- .../index/mapper/core/BooleanFieldMapper.java | 5 +- .../index/mapper/core/ByteFieldMapper.java | 5 +- .../mapper/core/CompletionFieldMapper.java | 37 +++++++-- .../index/mapper/core/DateFieldMapper.java | 8 +- .../index/mapper/core/DoubleFieldMapper.java | 5 +- .../index/mapper/core/FloatFieldMapper.java | 5 +- .../index/mapper/core/IntegerFieldMapper.java | 5 +- .../index/mapper/core/LongFieldMapper.java | 5 +- .../index/mapper/core/Murmur3FieldMapper.java | 7 +- .../index/mapper/core/ShortFieldMapper.java | 5 +- .../index/mapper/core/StringFieldMapper.java | 18 +++- .../mapper/core/TokenCountFieldMapper.java | 8 +- .../index/mapper/core/TypeParsers.java | 74 +++++++++++++++-- .../index/mapper/geo/GeoPointFieldMapper.java | 19 ++++- .../index/mapper/geo/GeoShapeFieldMapper.java | 9 +- .../index/mapper/internal/AllFieldMapper.java | 6 +- .../index/mapper/internal/AnalyzerMapper.java | 5 +- .../mapper/internal/BoostFieldMapper.java | 7 +- .../index/mapper/internal/IdFieldMapper.java | 5 +- .../mapper/internal/IndexFieldMapper.java | 5 +- .../mapper/internal/ParentFieldMapper.java | 7 +- .../mapper/internal/RoutingFieldMapper.java | 6 +- .../mapper/internal/SizeFieldMapper.java | 6 +- .../mapper/internal/SourceFieldMapper.java | 32 ++++--- .../index/mapper/internal/TTLFieldMapper.java | 6 +- .../mapper/internal/TimestampFieldMapper.java | 8 +- .../mapper/internal/VersionFieldMapper.java | 5 +- .../index/mapper/ip/IpFieldMapper.java | 5 +- .../index/mapper/object/ObjectMapper.java | 83 +++++++++++++++---- .../context/CategoryContextMapping.java | 2 + .../suggest/context/ContextBuilder.java | 20 +++-- .../context/GeolocationContextMapping.java | 9 ++ .../org/elasticsearch/get/GetActionTests.java | 17 ++-- .../mapper/externalvalues/ExternalMapper.java | 8 +- .../ExternalValuesMapperIntegrationTests.java | 4 +- .../SimpleExternalMappingTests.java | 4 +- .../index/mapper/simple/test-mapping.json | 4 - .../percolator/PercolatorTests.java | 54 +++++++++--- .../aggregations/bucket/ParentIdAggTests.java | 1 - .../search/fields/SearchFieldsTests.java | 12 +-- .../search/geo/GeoFilterTests.java | 5 +- .../highlight/HighlighterSearchTests.java | 2 +- .../search/query/MultiMatchQueryTests.java | 3 - .../GeoLocationContextMappingTest.java | 3 +- 46 files changed, 485 insertions(+), 142 deletions(-) diff --git a/src/main/java/org/elasticsearch/index/mapper/DocumentMapperParser.java b/src/main/java/org/elasticsearch/index/mapper/DocumentMapperParser.java index bfbc57042734c..2defebe5e9674 100644 --- a/src/main/java/org/elasticsearch/index/mapper/DocumentMapperParser.java +++ b/src/main/java/org/elasticsearch/index/mapper/DocumentMapperParser.java @@ -28,6 +28,8 @@ import org.elasticsearch.common.collect.Tuple; import org.elasticsearch.common.compress.CompressedString; import org.elasticsearch.common.geo.ShapesAvailability; +import org.elasticsearch.common.logging.ESLogger; +import org.elasticsearch.common.logging.Loggers; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentHelper; @@ -37,10 +39,37 @@ import org.elasticsearch.index.analysis.NamedAnalyzer; import org.elasticsearch.index.codec.docvaluesformat.DocValuesFormatService; import org.elasticsearch.index.codec.postingsformat.PostingsFormatService; -import org.elasticsearch.index.mapper.core.*; +import org.elasticsearch.index.mapper.core.BinaryFieldMapper; +import org.elasticsearch.index.mapper.core.BooleanFieldMapper; +import org.elasticsearch.index.mapper.core.ByteFieldMapper; +import org.elasticsearch.index.mapper.core.CompletionFieldMapper; +import org.elasticsearch.index.mapper.core.DateFieldMapper; +import org.elasticsearch.index.mapper.core.DoubleFieldMapper; +import org.elasticsearch.index.mapper.core.FloatFieldMapper; +import org.elasticsearch.index.mapper.core.IntegerFieldMapper; +import org.elasticsearch.index.mapper.core.LongFieldMapper; +import org.elasticsearch.index.mapper.core.Murmur3FieldMapper; +import org.elasticsearch.index.mapper.core.ShortFieldMapper; +import org.elasticsearch.index.mapper.core.StringFieldMapper; +import org.elasticsearch.index.mapper.core.TokenCountFieldMapper; +import org.elasticsearch.index.mapper.core.TypeParsers; import org.elasticsearch.index.mapper.geo.GeoPointFieldMapper; import org.elasticsearch.index.mapper.geo.GeoShapeFieldMapper; -import org.elasticsearch.index.mapper.internal.*; +import org.elasticsearch.index.mapper.internal.AllFieldMapper; +import org.elasticsearch.index.mapper.internal.AnalyzerMapper; +import org.elasticsearch.index.mapper.internal.BoostFieldMapper; +import org.elasticsearch.index.mapper.internal.FieldNamesFieldMapper; +import org.elasticsearch.index.mapper.internal.IdFieldMapper; +import org.elasticsearch.index.mapper.internal.IndexFieldMapper; +import org.elasticsearch.index.mapper.internal.ParentFieldMapper; +import org.elasticsearch.index.mapper.internal.RoutingFieldMapper; +import org.elasticsearch.index.mapper.internal.SizeFieldMapper; +import org.elasticsearch.index.mapper.internal.SourceFieldMapper; +import org.elasticsearch.index.mapper.internal.TTLFieldMapper; +import org.elasticsearch.index.mapper.internal.TimestampFieldMapper; +import org.elasticsearch.index.mapper.internal.TypeFieldMapper; +import org.elasticsearch.index.mapper.internal.UidFieldMapper; +import org.elasticsearch.index.mapper.internal.VersionFieldMapper; import org.elasticsearch.index.mapper.ip.IpFieldMapper; import org.elasticsearch.index.mapper.object.ObjectMapper; import org.elasticsearch.index.mapper.object.RootObjectMapper; @@ -63,6 +92,7 @@ public class DocumentMapperParser extends AbstractIndexComponent { final AnalysisService analysisService; + private static final ESLogger logger = Loggers.getLogger(DocumentMapperParser.class); private final PostingsFormatService postingsFormatService; private final DocValuesFormatService docValuesFormatService; private final SimilarityLookupService similarityLookupService; @@ -248,13 +278,13 @@ private DocumentMapper parse(String type, Map mapping, String de } else if ("transform".equals(fieldName)) { iterator.remove(); if (fieldNode instanceof Map) { - parseTransform(docBuilder, (Map) fieldNode); + parseTransform(docBuilder, (Map) fieldNode, parserContext.indexVersionCreated()); } else if (fieldNode instanceof List) { for (Object transformItem: (List)fieldNode) { if (!(transformItem instanceof Map)) { throw new MapperParsingException("Elements of transform list must be objects but one was: " + fieldNode); } - parseTransform(docBuilder, (Map) transformItem); + parseTransform(docBuilder, (Map) transformItem, parserContext.indexVersionCreated()); } } else { throw new MapperParsingException("Transform must be an object or an array but was: " + fieldNode); @@ -263,7 +293,10 @@ private DocumentMapper parse(String type, Map mapping, String de Mapper.TypeParser typeParser = rootTypeParsers.get(fieldName); if (typeParser != null) { iterator.remove(); - docBuilder.put(typeParser.parse(fieldName, (Map) fieldNode, parserContext)); + Map fieldNodeMap = (Map) fieldNode; + docBuilder.put(typeParser.parse(fieldName, fieldNodeMap, parserContext)); + fieldNodeMap.remove("type"); + checkNoRemainingFields(fieldName, fieldNodeMap, parserContext.indexVersionCreated()); } } } @@ -274,9 +307,8 @@ private DocumentMapper parse(String type, Map mapping, String de } docBuilder.meta(attributes); - if (!mapping.isEmpty()) { - throw new MapperParsingException("Root type mapping not empty after parsing! Remaining fields: " + getRemainingFields(mapping)); - } + checkNoRemainingFields(mapping, parserContext.indexVersionCreated(), "Root mapping definition has unsupported parameters: "); + if (!docBuilder.hasIndexAnalyzer()) { docBuilder.indexAnalyzer(analysisService.defaultIndexAnalyzer()); } @@ -293,16 +325,30 @@ private DocumentMapper parse(String type, Map mapping, String de return documentMapper; } - private String getRemainingFields(Map map) { + public static void checkNoRemainingFields(String fieldName, Map fieldNodeMap, Version indexVersionCreated) { + checkNoRemainingFields(fieldNodeMap, indexVersionCreated, "Mapping definition for [" + fieldName + "] has unsupported parameters: "); + } + + public static void checkNoRemainingFields(Map fieldNodeMap, Version indexVersionCreated, String message) { + if (!fieldNodeMap.isEmpty()) { + if (indexVersionCreated.onOrAfter(Version.V_2_0_0)) { + throw new MapperParsingException(message + getRemainingFields(fieldNodeMap)); + } else { + logger.debug(message + "{}", getRemainingFields(fieldNodeMap)); + } + } + } + + private static String getRemainingFields(Map map) { StringBuilder remainingFields = new StringBuilder(); for (String key : map.keySet()) { - remainingFields.append(" [").append(key).append(" : ").append(map.get(key).toString()).append("]"); + remainingFields.append(" [").append(key).append(" : ").append(map.get(key)).append("]"); } return remainingFields.toString(); } @SuppressWarnings("unchecked") - private void parseTransform(DocumentMapper.Builder docBuilder, Map transformConfig) { + private void parseTransform(DocumentMapper.Builder docBuilder, Map transformConfig, Version indexVersionCreated) { ScriptParameterParser scriptParameterParser = new ScriptParameterParser(); scriptParameterParser.parseConfig(transformConfig, true); @@ -319,9 +365,7 @@ private void parseTransform(DocumentMapper.Builder docBuilder, Map params = (Map)transformConfig.remove("params"); docBuilder.transform(scriptService, script, scriptType, scriptLang, params); } - if (!transformConfig.isEmpty()) { - throw new MapperParsingException("Unrecognized parameter in transform config: " + getRemainingFields(transformConfig)); - } + checkNoRemainingFields(transformConfig, indexVersionCreated, "Transform config has unsupported parameters: "); } private Tuple> extractMapping(String type, String source) throws MapperParsingException { diff --git a/src/main/java/org/elasticsearch/index/mapper/core/BinaryFieldMapper.java b/src/main/java/org/elasticsearch/index/mapper/core/BinaryFieldMapper.java index 152381a0c5fa0..1378360c923b9 100644 --- a/src/main/java/org/elasticsearch/index/mapper/core/BinaryFieldMapper.java +++ b/src/main/java/org/elasticsearch/index/mapper/core/BinaryFieldMapper.java @@ -47,6 +47,7 @@ import org.elasticsearch.index.mapper.*; import java.io.IOException; +import java.util.Iterator; import java.util.List; import java.util.Map; @@ -104,11 +105,13 @@ public static class TypeParser implements Mapper.TypeParser { public Mapper.Builder parse(String name, Map node, ParserContext parserContext) throws MapperParsingException { BinaryFieldMapper.Builder builder = binaryField(name); parseField(builder, name, node, parserContext); - for (Map.Entry entry : node.entrySet()) { + for (Iterator> iterator = node.entrySet().iterator(); iterator.hasNext();) { + Map.Entry entry = iterator.next(); String fieldName = Strings.toUnderscoreCase(entry.getKey()); Object fieldNode = entry.getValue(); if (fieldName.equals("compress") && fieldNode != null) { builder.compress(nodeBooleanValue(fieldNode)); + iterator.remove(); } else if (fieldName.equals("compress_threshold") && fieldNode != null) { if (fieldNode instanceof Number) { builder.compressThreshold(((Number) fieldNode).longValue()); @@ -117,6 +120,7 @@ public Mapper.Builder parse(String name, Map node, ParserContext builder.compressThreshold(ByteSizeValue.parseBytesSizeValue(fieldNode.toString()).bytes()); builder.compress(true); } + iterator.remove(); } } return builder; diff --git a/src/main/java/org/elasticsearch/index/mapper/core/BooleanFieldMapper.java b/src/main/java/org/elasticsearch/index/mapper/core/BooleanFieldMapper.java index 1c15bddd6bf35..c192ce92d9006 100644 --- a/src/main/java/org/elasticsearch/index/mapper/core/BooleanFieldMapper.java +++ b/src/main/java/org/elasticsearch/index/mapper/core/BooleanFieldMapper.java @@ -40,6 +40,7 @@ import org.elasticsearch.index.similarity.SimilarityProvider; import java.io.IOException; +import java.util.Iterator; import java.util.List; import java.util.Map; @@ -107,7 +108,8 @@ public static class TypeParser implements Mapper.TypeParser { public Mapper.Builder parse(String name, Map node, ParserContext parserContext) throws MapperParsingException { BooleanFieldMapper.Builder builder = booleanField(name); parseField(builder, name, node, parserContext); - for (Map.Entry entry : node.entrySet()) { + for (Iterator> iterator = node.entrySet().iterator(); iterator.hasNext();) { + Map.Entry entry = iterator.next(); String propName = Strings.toUnderscoreCase(entry.getKey()); Object propNode = entry.getValue(); if (propName.equals("null_value")) { @@ -115,6 +117,7 @@ public Mapper.Builder parse(String name, Map node, ParserContext throw new MapperParsingException("Property [null_value] cannot be null."); } builder.nullValue(nodeBooleanValue(propNode)); + iterator.remove(); } } return builder; diff --git a/src/main/java/org/elasticsearch/index/mapper/core/ByteFieldMapper.java b/src/main/java/org/elasticsearch/index/mapper/core/ByteFieldMapper.java index f500e5a386a7b..9df872e34ffcc 100644 --- a/src/main/java/org/elasticsearch/index/mapper/core/ByteFieldMapper.java +++ b/src/main/java/org/elasticsearch/index/mapper/core/ByteFieldMapper.java @@ -50,6 +50,7 @@ import org.elasticsearch.index.similarity.SimilarityProvider; import java.io.IOException; +import java.util.Iterator; import java.util.List; import java.util.Map; @@ -105,7 +106,8 @@ public static class TypeParser implements Mapper.TypeParser { public Mapper.Builder parse(String name, Map node, ParserContext parserContext) throws MapperParsingException { ByteFieldMapper.Builder builder = byteField(name); parseNumberField(builder, name, node, parserContext); - for (Map.Entry entry : node.entrySet()) { + for (Iterator> iterator = node.entrySet().iterator(); iterator.hasNext();) { + Map.Entry entry = iterator.next(); String propName = Strings.toUnderscoreCase(entry.getKey()); Object propNode = entry.getValue(); if (propName.equals("null_value")) { @@ -113,6 +115,7 @@ public Mapper.Builder parse(String name, Map node, ParserContext throw new MapperParsingException("Property [null_value] cannot be null."); } builder.nullValue(nodeByteValue(propNode)); + iterator.remove(); } } return builder; diff --git a/src/main/java/org/elasticsearch/index/mapper/core/CompletionFieldMapper.java b/src/main/java/org/elasticsearch/index/mapper/core/CompletionFieldMapper.java index f69b79847abcd..b945f83cda1c4 100644 --- a/src/main/java/org/elasticsearch/index/mapper/core/CompletionFieldMapper.java +++ b/src/main/java/org/elasticsearch/index/mapper/core/CompletionFieldMapper.java @@ -30,13 +30,20 @@ import org.elasticsearch.ElasticsearchIllegalArgumentException; import org.elasticsearch.ElasticsearchParseException; import org.elasticsearch.common.ParseField; -import org.elasticsearch.common.xcontent.*; +import org.elasticsearch.common.xcontent.XContentBuilder; +import org.elasticsearch.common.xcontent.XContentFactory; +import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.common.xcontent.XContentParser.NumberType; import org.elasticsearch.common.xcontent.XContentParser.Token; import org.elasticsearch.index.analysis.NamedAnalyzer; import org.elasticsearch.index.codec.postingsformat.PostingsFormatProvider; import org.elasticsearch.index.fielddata.FieldDataType; -import org.elasticsearch.index.mapper.*; +import org.elasticsearch.index.mapper.Mapper; +import org.elasticsearch.index.mapper.MapperException; +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.similarity.SimilarityProvider; import org.elasticsearch.search.suggest.completion.AnalyzingCompletionLookupProvider; import org.elasticsearch.search.suggest.completion.CompletionPostingsFormatProvider; @@ -46,7 +53,12 @@ import org.elasticsearch.search.suggest.context.ContextMapping.ContextConfig; import java.io.IOException; -import java.util.*; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Set; +import java.util.SortedMap; import static org.elasticsearch.index.mapper.MapperBuilders.completionField; import static org.elasticsearch.index.mapper.core.TypeParsers.parseMultiField; @@ -147,7 +159,8 @@ public static class TypeParser implements Mapper.TypeParser { @Override public Mapper.Builder parse(String name, Map node, ParserContext parserContext) throws MapperParsingException { CompletionFieldMapper.Builder builder = completionField(name); - for (Map.Entry entry : node.entrySet()) { + for (Iterator> iterator = node.entrySet().iterator(); iterator.hasNext();) { + Map.Entry entry = iterator.next(); String fieldName = entry.getKey(); Object fieldNode = entry.getValue(); if (fieldName.equals("type")) { @@ -157,24 +170,32 @@ public static class TypeParser implements Mapper.TypeParser { NamedAnalyzer analyzer = getNamedAnalyzer(parserContext, fieldNode.toString()); builder.indexAnalyzer(analyzer); builder.searchAnalyzer(analyzer); + iterator.remove(); } else if (Fields.INDEX_ANALYZER.match(fieldName)) { builder.indexAnalyzer(getNamedAnalyzer(parserContext, fieldNode.toString())); + iterator.remove(); } else if (Fields.SEARCH_ANALYZER.match(fieldName)) { builder.searchAnalyzer(getNamedAnalyzer(parserContext, fieldNode.toString())); + iterator.remove(); } else if (fieldName.equals(Fields.PAYLOADS)) { builder.payloads(Boolean.parseBoolean(fieldNode.toString())); + iterator.remove(); } else if (Fields.PRESERVE_SEPARATORS.match(fieldName)) { builder.preserveSeparators(Boolean.parseBoolean(fieldNode.toString())); + iterator.remove(); } else if (Fields.PRESERVE_POSITION_INCREMENTS.match(fieldName)) { builder.preservePositionIncrements(Boolean.parseBoolean(fieldNode.toString())); + iterator.remove(); } else if (Fields.MAX_INPUT_LENGTH.match(fieldName)) { builder.maxInputLength(Integer.parseInt(fieldNode.toString())); + iterator.remove(); } else if ("fields".equals(fieldName) || "path".equals(fieldName)) { - parseMultiField(builder, name, parserContext, fieldName, fieldNode); + if (parseMultiField(builder, name, parserContext, fieldName, fieldNode)) { + iterator.remove(); + } } else if (fieldName.equals(Fields.CONTEXT)) { - builder.contextMapping(ContextBuilder.loadMappings(fieldNode)); - } else { - throw new MapperParsingException("Unknown field [" + fieldName + "]"); + builder.contextMapping(ContextBuilder.loadMappings(fieldNode, parserContext.indexVersionCreated())); + iterator.remove(); } } diff --git a/src/main/java/org/elasticsearch/index/mapper/core/DateFieldMapper.java b/src/main/java/org/elasticsearch/index/mapper/core/DateFieldMapper.java index fc319d37674ce..68f5e15aaef10 100644 --- a/src/main/java/org/elasticsearch/index/mapper/core/DateFieldMapper.java +++ b/src/main/java/org/elasticsearch/index/mapper/core/DateFieldMapper.java @@ -56,6 +56,7 @@ import org.joda.time.DateTimeZone; import java.io.IOException; +import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; @@ -149,7 +150,8 @@ public static class TypeParser implements Mapper.TypeParser { public Mapper.Builder parse(String name, Map node, ParserContext parserContext) throws MapperParsingException { DateFieldMapper.Builder builder = dateField(name); parseNumberField(builder, name, node, parserContext); - for (Map.Entry entry : node.entrySet()) { + for (Iterator> iterator = node.entrySet().iterator(); iterator.hasNext();) { + Map.Entry entry = iterator.next(); String propName = Strings.toUnderscoreCase(entry.getKey()); Object propNode = entry.getValue(); if (propName.equals("null_value")) { @@ -157,12 +159,16 @@ public static class TypeParser implements Mapper.TypeParser { throw new MapperParsingException("Property [null_value] cannot be null."); } builder.nullValue(propNode.toString()); + iterator.remove(); } else if (propName.equals("format")) { builder.dateTimeFormatter(parseDateTimeFormatter(propNode)); + iterator.remove(); } else if (propName.equals("numeric_resolution")) { builder.timeUnit(TimeUnit.valueOf(propNode.toString().toUpperCase(Locale.ROOT))); + iterator.remove(); } else if (propName.equals("locale")) { builder.locale(LocaleUtils.parse(propNode.toString())); + iterator.remove(); } } return builder; diff --git a/src/main/java/org/elasticsearch/index/mapper/core/DoubleFieldMapper.java b/src/main/java/org/elasticsearch/index/mapper/core/DoubleFieldMapper.java index 985ec982a33be..4ad971140dd42 100644 --- a/src/main/java/org/elasticsearch/index/mapper/core/DoubleFieldMapper.java +++ b/src/main/java/org/elasticsearch/index/mapper/core/DoubleFieldMapper.java @@ -55,6 +55,7 @@ import org.elasticsearch.index.similarity.SimilarityProvider; import java.io.IOException; +import java.util.Iterator; import java.util.List; import java.util.Map; @@ -109,7 +110,8 @@ public static class TypeParser implements Mapper.TypeParser { public Mapper.Builder parse(String name, Map node, ParserContext parserContext) throws MapperParsingException { DoubleFieldMapper.Builder builder = doubleField(name); parseNumberField(builder, name, node, parserContext); - for (Map.Entry entry : node.entrySet()) { + for (Iterator> iterator = node.entrySet().iterator(); iterator.hasNext();) { + Map.Entry entry = iterator.next(); String propName = entry.getKey(); Object propNode = entry.getValue(); if (propName.equals("nullValue") || propName.equals("null_value")) { @@ -117,6 +119,7 @@ public Mapper.Builder parse(String name, Map node, ParserContext throw new MapperParsingException("Property [null_value] cannot be null."); } builder.nullValue(nodeDoubleValue(propNode)); + iterator.remove(); } } return builder; diff --git a/src/main/java/org/elasticsearch/index/mapper/core/FloatFieldMapper.java b/src/main/java/org/elasticsearch/index/mapper/core/FloatFieldMapper.java index 2accfb10e1864..d342b3ba8c624 100644 --- a/src/main/java/org/elasticsearch/index/mapper/core/FloatFieldMapper.java +++ b/src/main/java/org/elasticsearch/index/mapper/core/FloatFieldMapper.java @@ -55,6 +55,7 @@ import org.elasticsearch.index.similarity.SimilarityProvider; import java.io.IOException; +import java.util.Iterator; import java.util.List; import java.util.Map; @@ -109,7 +110,8 @@ public static class TypeParser implements Mapper.TypeParser { public Mapper.Builder parse(String name, Map node, ParserContext parserContext) throws MapperParsingException { FloatFieldMapper.Builder builder = floatField(name); parseNumberField(builder, name, node, parserContext); - for (Map.Entry entry : node.entrySet()) { + for (Iterator> iterator = node.entrySet().iterator(); iterator.hasNext();) { + Map.Entry entry = iterator.next(); String propName = Strings.toUnderscoreCase(entry.getKey()); Object propNode = entry.getValue(); if (propName.equals("null_value")) { @@ -117,6 +119,7 @@ public Mapper.Builder parse(String name, Map node, ParserContext throw new MapperParsingException("Property [null_value] cannot be null."); } builder.nullValue(nodeFloatValue(propNode)); + iterator.remove(); } } return builder; diff --git a/src/main/java/org/elasticsearch/index/mapper/core/IntegerFieldMapper.java b/src/main/java/org/elasticsearch/index/mapper/core/IntegerFieldMapper.java index 4a664b4d5a2a8..46ed834935193 100644 --- a/src/main/java/org/elasticsearch/index/mapper/core/IntegerFieldMapper.java +++ b/src/main/java/org/elasticsearch/index/mapper/core/IntegerFieldMapper.java @@ -51,6 +51,7 @@ import org.elasticsearch.index.similarity.SimilarityProvider; import java.io.IOException; +import java.util.Iterator; import java.util.List; import java.util.Map; @@ -105,7 +106,8 @@ public static class TypeParser implements Mapper.TypeParser { public Mapper.Builder parse(String name, Map node, ParserContext parserContext) throws MapperParsingException { IntegerFieldMapper.Builder builder = integerField(name); parseNumberField(builder, name, node, parserContext); - for (Map.Entry entry : node.entrySet()) { + for (Iterator> iterator = node.entrySet().iterator(); iterator.hasNext();) { + Map.Entry entry = iterator.next(); String propName = Strings.toUnderscoreCase(entry.getKey()); Object propNode = entry.getValue(); if (propName.equals("null_value")) { @@ -113,6 +115,7 @@ public Mapper.Builder parse(String name, Map node, ParserContext throw new MapperParsingException("Property [null_value] cannot be null."); } builder.nullValue(nodeIntegerValue(propNode)); + iterator.remove(); } } return builder; diff --git a/src/main/java/org/elasticsearch/index/mapper/core/LongFieldMapper.java b/src/main/java/org/elasticsearch/index/mapper/core/LongFieldMapper.java index 2ebc04ae7d2fb..dda87463a3b5e 100644 --- a/src/main/java/org/elasticsearch/index/mapper/core/LongFieldMapper.java +++ b/src/main/java/org/elasticsearch/index/mapper/core/LongFieldMapper.java @@ -51,6 +51,7 @@ import org.elasticsearch.index.similarity.SimilarityProvider; import java.io.IOException; +import java.util.Iterator; import java.util.List; import java.util.Map; @@ -105,7 +106,8 @@ public static class TypeParser implements Mapper.TypeParser { public Mapper.Builder parse(String name, Map node, ParserContext parserContext) throws MapperParsingException { LongFieldMapper.Builder builder = longField(name); parseNumberField(builder, name, node, parserContext); - for (Map.Entry entry : node.entrySet()) { + for (Iterator> iterator = node.entrySet().iterator(); iterator.hasNext();) { + Map.Entry entry = iterator.next(); String propName = Strings.toUnderscoreCase(entry.getKey()); Object propNode = entry.getValue(); if (propName.equals("null_value")) { @@ -113,6 +115,7 @@ public Mapper.Builder parse(String name, Map node, ParserContext throw new MapperParsingException("Property [null_value] cannot be null."); } builder.nullValue(nodeLongValue(propNode)); + iterator.remove(); } } return builder; diff --git a/src/main/java/org/elasticsearch/index/mapper/core/Murmur3FieldMapper.java b/src/main/java/org/elasticsearch/index/mapper/core/Murmur3FieldMapper.java index 1b8ba8a9a45d9..b18891092dc1f 100644 --- a/src/main/java/org/elasticsearch/index/mapper/core/Murmur3FieldMapper.java +++ b/src/main/java/org/elasticsearch/index/mapper/core/Murmur3FieldMapper.java @@ -58,7 +58,7 @@ public Builder(String name) { @Override public Murmur3FieldMapper build(BuilderContext context) { fieldType.setOmitNorms(fieldType.omitNorms() && boost == 1.0f); - Murmur3FieldMapper fieldMapper = new Murmur3FieldMapper(buildNames(context), fieldType.numericPrecisionStep(), boost, fieldType, docValues, ~0L, + Murmur3FieldMapper fieldMapper = new Murmur3FieldMapper(buildNames(context), fieldType.numericPrecisionStep(), boost, fieldType, docValues, null, ignoreMalformed(context), coerce(context), postingsProvider, docValuesProvider, similarity, normsLoading, fieldDataSettings, context.indexSettings(), multiFieldsBuilder.build(this, context), copyTo); fieldMapper.includeInAll(includeInAll); @@ -72,6 +72,11 @@ public static class TypeParser implements Mapper.TypeParser { public Mapper.Builder parse(String name, Map node, ParserContext parserContext) throws MapperParsingException { Builder builder = murmur3Field(name); parseNumberField(builder, name, node, parserContext); + // Because this mapper extends LongFieldMapper the null_value field will be added to the JSON when transferring cluster state + // between nodes so we have to remove the entry here so that the validation doesn't fail + // TODO should murmur3 support null_value? at the moment if a user sets null_value it has to be silently ignored since we can't + // determine whether the JSON is the original JSON from the user or if its the serialised cluster state being passed between nodes. +// node.remove("null_value"); return builder; } } diff --git a/src/main/java/org/elasticsearch/index/mapper/core/ShortFieldMapper.java b/src/main/java/org/elasticsearch/index/mapper/core/ShortFieldMapper.java index 195a5e8a3b4e0..5470811c0570f 100644 --- a/src/main/java/org/elasticsearch/index/mapper/core/ShortFieldMapper.java +++ b/src/main/java/org/elasticsearch/index/mapper/core/ShortFieldMapper.java @@ -52,6 +52,7 @@ import org.elasticsearch.index.similarity.SimilarityProvider; import java.io.IOException; +import java.util.Iterator; import java.util.List; import java.util.Map; @@ -107,7 +108,8 @@ public static class TypeParser implements Mapper.TypeParser { public Mapper.Builder parse(String name, Map node, ParserContext parserContext) throws MapperParsingException { ShortFieldMapper.Builder builder = shortField(name); parseNumberField(builder, name, node, parserContext); - for (Map.Entry entry : node.entrySet()) { + for (Iterator> iterator = node.entrySet().iterator(); iterator.hasNext();) { + Map.Entry entry = iterator.next(); String propName = Strings.toUnderscoreCase(entry.getKey()); Object propNode = entry.getValue(); if (propName.equals("null_value")) { @@ -115,6 +117,7 @@ public Mapper.Builder parse(String name, Map node, ParserContext throw new MapperParsingException("Property [null_value] cannot be null."); } builder.nullValue(nodeShortValue(propNode)); + iterator.remove(); } } return builder; diff --git a/src/main/java/org/elasticsearch/index/mapper/core/StringFieldMapper.java b/src/main/java/org/elasticsearch/index/mapper/core/StringFieldMapper.java index 573a9b9e9979d..24daeef2c2f71 100644 --- a/src/main/java/org/elasticsearch/index/mapper/core/StringFieldMapper.java +++ b/src/main/java/org/elasticsearch/index/mapper/core/StringFieldMapper.java @@ -37,11 +37,16 @@ import org.elasticsearch.index.codec.docvaluesformat.DocValuesFormatProvider; import org.elasticsearch.index.codec.postingsformat.PostingsFormatProvider; import org.elasticsearch.index.fielddata.FieldDataType; -import org.elasticsearch.index.mapper.*; +import org.elasticsearch.index.mapper.Mapper; +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.internal.AllFieldMapper; import org.elasticsearch.index.similarity.SimilarityProvider; import java.io.IOException; +import java.util.Iterator; import java.util.List; import java.util.Map; @@ -151,7 +156,8 @@ public static class TypeParser implements Mapper.TypeParser { public Mapper.Builder parse(String name, Map node, ParserContext parserContext) throws MapperParsingException { StringFieldMapper.Builder builder = stringField(name); parseField(builder, name, node, parserContext); - for (Map.Entry entry : node.entrySet()) { + for (Iterator> iterator = node.entrySet().iterator(); iterator.hasNext();) { + Map.Entry entry = iterator.next(); String propName = Strings.toUnderscoreCase(entry.getKey()); Object propNode = entry.getValue(); if (propName.equals("null_value")) { @@ -159,12 +165,14 @@ public Mapper.Builder parse(String name, Map node, ParserContext throw new MapperParsingException("Property [null_value] cannot be null."); } builder.nullValue(propNode.toString()); + iterator.remove(); } else if (propName.equals("search_quote_analyzer")) { NamedAnalyzer analyzer = parserContext.analysisService().analyzer(propNode.toString()); if (analyzer == null) { throw new MapperParsingException("Analyzer [" + propNode.toString() + "] not found for field [" + name + "]"); } builder.searchQuotedAnalyzer(analyzer); + iterator.remove(); } else if (propName.equals("position_offset_gap")) { builder.positionOffsetGap(XContentMapValues.nodeIntegerValue(propNode, -1)); // we need to update to actual analyzers if they are not set in this case... @@ -178,10 +186,12 @@ public Mapper.Builder parse(String name, Map node, ParserContext if (builder.searchQuotedAnalyzer == null) { builder.searchQuotedAnalyzer = parserContext.analysisService().defaultSearchQuoteAnalyzer(); } + iterator.remove(); } else if (propName.equals("ignore_above")) { builder.ignoreAbove(XContentMapValues.nodeIntegerValue(propNode, -1)); - } else { - parseMultiField(builder, name, parserContext, propName, propNode); + iterator.remove(); + } else if (parseMultiField(builder, name, parserContext, propName, propNode)) { + iterator.remove(); } } return builder; diff --git a/src/main/java/org/elasticsearch/index/mapper/core/TokenCountFieldMapper.java b/src/main/java/org/elasticsearch/index/mapper/core/TokenCountFieldMapper.java index a43dc7daccd62..1b94a3409f2b9 100644 --- a/src/main/java/org/elasticsearch/index/mapper/core/TokenCountFieldMapper.java +++ b/src/main/java/org/elasticsearch/index/mapper/core/TokenCountFieldMapper.java @@ -36,6 +36,7 @@ import org.elasticsearch.index.similarity.SimilarityProvider; import java.io.IOException; +import java.util.Iterator; import java.util.List; import java.util.Map; @@ -92,20 +93,23 @@ public static class TypeParser implements Mapper.TypeParser { @SuppressWarnings("unchecked") public Mapper.Builder parse(String name, Map node, ParserContext parserContext) throws MapperParsingException { TokenCountFieldMapper.Builder builder = tokenCountField(name); - parseNumberField(builder, name, node, parserContext); - for (Map.Entry entry : node.entrySet()) { + for (Iterator> iterator = node.entrySet().iterator(); iterator.hasNext();) { + Map.Entry entry = iterator.next(); String propName = Strings.toUnderscoreCase(entry.getKey()); Object propNode = entry.getValue(); if (propName.equals("null_value")) { builder.nullValue(nodeIntegerValue(propNode)); + iterator.remove(); } else if (propName.equals("analyzer")) { NamedAnalyzer analyzer = parserContext.analysisService().analyzer(propNode.toString()); if (analyzer == null) { throw new MapperParsingException("Analyzer [" + propNode.toString() + "] not found for field [" + name + "]"); } builder.analyzer(analyzer); + iterator.remove(); } } + parseNumberField(builder, name, node, parserContext); if (builder.analyzer() == null) { throw new MapperParsingException("Analyzer must be set for field [" + name + "] but wasn't."); } diff --git a/src/main/java/org/elasticsearch/index/mapper/core/TypeParsers.java b/src/main/java/org/elasticsearch/index/mapper/core/TypeParsers.java index ccbffafe03544..6f06b4564e076 100644 --- a/src/main/java/org/elasticsearch/index/mapper/core/TypeParsers.java +++ b/src/main/java/org/elasticsearch/index/mapper/core/TypeParsers.java @@ -30,16 +30,24 @@ import org.elasticsearch.common.settings.loader.SettingsLoader; import org.elasticsearch.index.analysis.NamedAnalyzer; import org.elasticsearch.index.mapper.ContentPath; +import org.elasticsearch.index.mapper.DocumentMapperParser; import org.elasticsearch.index.mapper.FieldMapper.Loading; import org.elasticsearch.index.mapper.Mapper; import org.elasticsearch.index.mapper.MapperParsingException; import java.util.ArrayList; import java.util.Collections; +import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Map.Entry; -import static org.elasticsearch.common.xcontent.support.XContentMapValues.*; +import static org.elasticsearch.common.xcontent.support.XContentMapValues.isArray; +import static org.elasticsearch.common.xcontent.support.XContentMapValues.nodeBooleanValue; +import static org.elasticsearch.common.xcontent.support.XContentMapValues.nodeFloatValue; +import static org.elasticsearch.common.xcontent.support.XContentMapValues.nodeIntegerValue; +import static org.elasticsearch.common.xcontent.support.XContentMapValues.nodeMapValue; +import static org.elasticsearch.common.xcontent.support.XContentMapValues.nodeStringValue; import static org.elasticsearch.index.mapper.FieldMapper.DOC_VALUES_FORMAT; /** @@ -57,14 +65,17 @@ public class TypeParsers { List fields = null; String firstType = null; - for (Map.Entry entry : node.entrySet()) { + for (Iterator> iterator = node.entrySet().iterator(); iterator.hasNext();) { + Map.Entry entry = iterator.next(); String fieldName = Strings.toUnderscoreCase(entry.getKey()); Object fieldNode = entry.getValue(); if (fieldName.equals("path")) { pathType = parsePathType(name, fieldNode.toString()); + iterator.remove(); } else if (fieldName.equals("fields")) { Map fieldsNode = (Map) fieldNode; - for (Map.Entry entry1 : fieldsNode.entrySet()) { + for (Iterator> fieldsIterator = fieldsNode.entrySet().iterator(); fieldsIterator.hasNext();) { + Map.Entry entry1 = fieldsIterator.next(); String propName = entry1.getKey(); Map propNode = (Map) entry1.getValue(); @@ -85,13 +96,18 @@ public class TypeParsers { } if (propName.equals(name)) { mainFieldBuilder = (AbstractFieldMapper.Builder) typeParser.parse(propName, propNode, parserContext); + fieldsIterator.remove(); } else { if (fields == null) { fields = new ArrayList<>(2); } fields.add((AbstractFieldMapper.Builder) typeParser.parse(propName, propNode, parserContext)); + fieldsIterator.remove(); } } + fieldsNode.remove("type"); + DocumentMapperParser.checkNoRemainingFields(fieldName, fieldsNode, parserContext.indexVersionCreated()); + iterator.remove(); } } @@ -140,64 +156,88 @@ public class TypeParsers { public static void parseNumberField(NumberFieldMapper.Builder builder, String name, Map numberNode, Mapper.TypeParser.ParserContext parserContext) { parseField(builder, name, numberNode, parserContext); - for (Map.Entry entry : numberNode.entrySet()) { + for (Iterator> iterator = numberNode.entrySet().iterator(); iterator.hasNext();) { + Map.Entry entry = iterator.next(); String propName = Strings.toUnderscoreCase(entry.getKey()); Object propNode = entry.getValue(); if (propName.equals("precision_step")) { builder.precisionStep(nodeIntegerValue(propNode)); + iterator.remove(); } else if (propName.equals("ignore_malformed")) { builder.ignoreMalformed(nodeBooleanValue(propNode)); + iterator.remove(); } else if (propName.equals("coerce")) { builder.coerce(nodeBooleanValue(propNode)); + iterator.remove(); } else if (propName.equals("omit_norms")) { builder.omitNorms(nodeBooleanValue(propNode)); + iterator.remove(); } else if (propName.equals("similarity")) { builder.similarity(parserContext.similarityLookupService().similarity(propNode.toString())); - } else { - parseMultiField(builder, name, parserContext, propName, propNode); + iterator.remove(); + } else if (parseMultiField(builder, name, parserContext, propName, propNode)) { + iterator.remove(); } } } public static void parseField(AbstractFieldMapper.Builder builder, String name, Map fieldNode, Mapper.TypeParser.ParserContext parserContext) { - for (Map.Entry entry : fieldNode.entrySet()) { + for (Iterator> iterator = fieldNode.entrySet().iterator(); iterator.hasNext();) { + Map.Entry entry = iterator.next(); final String propName = Strings.toUnderscoreCase(entry.getKey()); final Object propNode = entry.getValue(); if (propName.equals("index_name")) { builder.indexName(propNode.toString()); + iterator.remove(); } else if (propName.equals("store")) { builder.store(parseStore(name, propNode.toString())); + iterator.remove(); } else if (propName.equals("index")) { parseIndex(name, propNode.toString(), builder); + iterator.remove(); } else if (propName.equals("tokenized")) { builder.tokenized(nodeBooleanValue(propNode)); + iterator.remove(); } else if (propName.equals(DOC_VALUES)) { builder.docValues(nodeBooleanValue(propNode)); + iterator.remove(); } else if (propName.equals("term_vector")) { parseTermVector(name, propNode.toString(), builder); + iterator.remove(); } else if (propName.equals("boost")) { builder.boost(nodeFloatValue(propNode)); + iterator.remove(); } else if (propName.equals("store_term_vectors")) { builder.storeTermVectors(nodeBooleanValue(propNode)); + iterator.remove(); } else if (propName.equals("store_term_vector_offsets")) { builder.storeTermVectorOffsets(nodeBooleanValue(propNode)); + iterator.remove(); } else if (propName.equals("store_term_vector_positions")) { builder.storeTermVectorPositions(nodeBooleanValue(propNode)); + iterator.remove(); } else if (propName.equals("store_term_vector_payloads")) { builder.storeTermVectorPayloads(nodeBooleanValue(propNode)); + iterator.remove(); } else if (propName.equals("omit_norms")) { builder.omitNorms(nodeBooleanValue(propNode)); + iterator.remove(); } else if (propName.equals("norms")) { final Map properties = nodeMapValue(propNode, "norms"); - for (Map.Entry entry2 : properties.entrySet()) { + for (Iterator> propsIterator = properties.entrySet().iterator(); propsIterator.hasNext();) { + Entry entry2 = propsIterator.next(); final String propName2 = Strings.toUnderscoreCase(entry2.getKey()); final Object propNode2 = entry2.getValue(); if (propName2.equals("enabled")) { builder.omitNorms(!nodeBooleanValue(propNode2)); + propsIterator.remove(); } else if (propName2.equals(Loading.KEY)) { builder.normsLoading(Loading.parse(nodeStringValue(propNode2, null), null)); + propsIterator.remove(); } } + DocumentMapperParser.checkNoRemainingFields(propName, properties, parserContext.indexVersionCreated()); + iterator.remove(); } else if (propName.equals("omit_term_freq_and_positions")) { final IndexOptions op = nodeBooleanValue(propNode) ? IndexOptions.DOCS : IndexOptions.DOCS_AND_FREQS_AND_POSITIONS; if (parserContext.indexVersionCreated().onOrAfter(Version.V_1_0_0_RC2)) { @@ -205,8 +245,10 @@ public static void parseField(AbstractFieldMapper.Builder builder, String name, } // deprecated option for BW compat builder.indexOptions(op); + iterator.remove(); } else if (propName.equals("index_options")) { builder.indexOptions(nodeIndexOptionValue(propNode)); + iterator.remove(); } else if (propName.equals("analyzer")) { NamedAnalyzer analyzer = parserContext.analysisService().analyzer(propNode.toString()); if (analyzer == null) { @@ -214,40 +256,50 @@ public static void parseField(AbstractFieldMapper.Builder builder, String name, } builder.indexAnalyzer(analyzer); builder.searchAnalyzer(analyzer); + iterator.remove(); } else if (propName.equals("index_analyzer")) { NamedAnalyzer analyzer = parserContext.analysisService().analyzer(propNode.toString()); if (analyzer == null) { throw new MapperParsingException("Analyzer [" + propNode.toString() + "] not found for field [" + name + "]"); } builder.indexAnalyzer(analyzer); + iterator.remove(); } else if (propName.equals("search_analyzer")) { NamedAnalyzer analyzer = parserContext.analysisService().analyzer(propNode.toString()); if (analyzer == null) { throw new MapperParsingException("Analyzer [" + propNode.toString() + "] not found for field [" + name + "]"); } builder.searchAnalyzer(analyzer); + iterator.remove(); } else if (propName.equals("include_in_all")) { builder.includeInAll(nodeBooleanValue(propNode)); + iterator.remove(); } else if (propName.equals("postings_format")) { String postingFormatName = propNode.toString(); builder.postingsFormat(parserContext.postingFormatService().get(postingFormatName)); + iterator.remove(); } else if (propName.equals(DOC_VALUES_FORMAT)) { String docValuesFormatName = propNode.toString(); builder.docValuesFormat(parserContext.docValuesFormatService().get(docValuesFormatName)); + iterator.remove(); } else if (propName.equals("similarity")) { builder.similarity(parserContext.similarityLookupService().similarity(propNode.toString())); + iterator.remove(); } else if (propName.equals("fielddata")) { final Settings settings = ImmutableSettings.builder().put(SettingsLoader.Helper.loadNestedFromMap(nodeMapValue(propNode, "fielddata"))).build(); builder.fieldDataSettings(settings); + iterator.remove(); } else if (propName.equals("copy_to")) { parseCopyFields(propNode, builder); + iterator.remove(); } } } - public static void parseMultiField(AbstractFieldMapper.Builder builder, String name, Mapper.TypeParser.ParserContext parserContext, String propName, Object propNode) { + public static boolean parseMultiField(AbstractFieldMapper.Builder builder, String name, Mapper.TypeParser.ParserContext parserContext, String propName, Object propNode) { if (propName.equals("path")) { builder.multiFieldPathType(parsePathType(name, propNode.toString())); + return true; } else if (propName.equals("fields")) { final Map multiFieldsPropNodes; @@ -282,8 +334,12 @@ public static void parseMultiField(AbstractFieldMapper.Builder builder, String n throw new MapperParsingException("No handler for type [" + type + "] declared on field [" + multiFieldName + "]"); } builder.addMultiField(typeParser.parse(multiFieldName, multiFieldNodes, parserContext)); + multiFieldNodes.remove("type"); + DocumentMapperParser.checkNoRemainingFields(propName, multiFieldNodes, parserContext.indexVersionCreated()); } + return true; } + return false; } private static IndexOptions nodeIndexOptionValue(final Object propNode) { diff --git a/src/main/java/org/elasticsearch/index/mapper/geo/GeoPointFieldMapper.java b/src/main/java/org/elasticsearch/index/mapper/geo/GeoPointFieldMapper.java index a0f98949c4a6e..6a5e5572838c9 100644 --- a/src/main/java/org/elasticsearch/index/mapper/geo/GeoPointFieldMapper.java +++ b/src/main/java/org/elasticsearch/index/mapper/geo/GeoPointFieldMapper.java @@ -207,44 +207,57 @@ public static class TypeParser implements Mapper.TypeParser { public Mapper.Builder parse(String name, Map node, ParserContext parserContext) throws MapperParsingException { Builder builder = geoPointField(name); parseField(builder, name, node, parserContext); - for (Map.Entry entry : node.entrySet()) { + for (Iterator> iterator = node.entrySet().iterator(); iterator.hasNext();) { + Map.Entry entry = iterator.next(); String fieldName = Strings.toUnderscoreCase(entry.getKey()); Object fieldNode = entry.getValue(); if (fieldName.equals("path")) { builder.multiFieldPathType(parsePathType(name, fieldNode.toString())); + iterator.remove(); } else if (fieldName.equals("lat_lon")) { builder.enableLatLon(XContentMapValues.nodeBooleanValue(fieldNode)); + iterator.remove(); } else if (fieldName.equals("geohash")) { builder.enableGeoHash(XContentMapValues.nodeBooleanValue(fieldNode)); + iterator.remove(); } else if (fieldName.equals("geohash_prefix")) { builder.geohashPrefix(XContentMapValues.nodeBooleanValue(fieldNode)); if (XContentMapValues.nodeBooleanValue(fieldNode)) { builder.enableGeoHash(true); } + iterator.remove(); } else if (fieldName.equals("precision_step")) { builder.precisionStep(XContentMapValues.nodeIntegerValue(fieldNode)); + iterator.remove(); } else if (fieldName.equals("geohash_precision")) { if (fieldNode instanceof Integer) { builder.geoHashPrecision(XContentMapValues.nodeIntegerValue(fieldNode)); } else { builder.geoHashPrecision(GeoUtils.geoHashLevelsForPrecision(fieldNode.toString())); } + iterator.remove(); } else if (fieldName.equals("validate")) { builder.validateLat = XContentMapValues.nodeBooleanValue(fieldNode); builder.validateLon = XContentMapValues.nodeBooleanValue(fieldNode); + iterator.remove(); } else if (fieldName.equals("validate_lon")) { builder.validateLon = XContentMapValues.nodeBooleanValue(fieldNode); + iterator.remove(); } else if (fieldName.equals("validate_lat")) { builder.validateLat = XContentMapValues.nodeBooleanValue(fieldNode); + iterator.remove(); } else if (fieldName.equals("normalize")) { builder.normalizeLat = XContentMapValues.nodeBooleanValue(fieldNode); builder.normalizeLon = XContentMapValues.nodeBooleanValue(fieldNode); + iterator.remove(); } else if (fieldName.equals("normalize_lat")) { builder.normalizeLat = XContentMapValues.nodeBooleanValue(fieldNode); + iterator.remove(); } else if (fieldName.equals("normalize_lon")) { builder.normalizeLon = XContentMapValues.nodeBooleanValue(fieldNode); - } else { - parseMultiField(builder, name, parserContext, fieldName, fieldNode); + iterator.remove(); + } else if (parseMultiField(builder, name, parserContext, fieldName, fieldNode)) { + iterator.remove(); } } return builder; diff --git a/src/main/java/org/elasticsearch/index/mapper/geo/GeoShapeFieldMapper.java b/src/main/java/org/elasticsearch/index/mapper/geo/GeoShapeFieldMapper.java index b1ca4a0c2544c..5b1f03599246a 100644 --- a/src/main/java/org/elasticsearch/index/mapper/geo/GeoShapeFieldMapper.java +++ b/src/main/java/org/elasticsearch/index/mapper/geo/GeoShapeFieldMapper.java @@ -45,6 +45,7 @@ import org.elasticsearch.index.mapper.core.AbstractFieldMapper; import java.io.IOException; +import java.util.Iterator; import java.util.List; import java.util.Map; @@ -172,19 +173,25 @@ public static class TypeParser implements Mapper.TypeParser { public Mapper.Builder parse(String name, Map node, ParserContext parserContext) throws MapperParsingException { Builder builder = geoShapeField(name); - for (Map.Entry entry : node.entrySet()) { + for (Iterator> iterator = node.entrySet().iterator(); iterator.hasNext();) { + Map.Entry entry = iterator.next(); String fieldName = Strings.toUnderscoreCase(entry.getKey()); Object fieldNode = entry.getValue(); if (Names.TREE.equals(fieldName)) { builder.tree(fieldNode.toString()); + iterator.remove(); } else if (Names.TREE_LEVELS.equals(fieldName)) { builder.treeLevels(Integer.parseInt(fieldNode.toString())); + iterator.remove(); } else if (Names.TREE_PRESISION.equals(fieldName)) { builder.treeLevelsByDistance(DistanceUnit.parse(fieldNode.toString(), DistanceUnit.DEFAULT, DistanceUnit.DEFAULT)); + iterator.remove(); } else if (Names.DISTANCE_ERROR_PCT.equals(fieldName)) { builder.distanceErrorPct(Double.parseDouble(fieldNode.toString())); + iterator.remove(); } else if (Names.STRATEGY.equals(fieldName)) { builder.strategy(fieldNode.toString()); + iterator.remove(); } } return builder; diff --git a/src/main/java/org/elasticsearch/index/mapper/internal/AllFieldMapper.java b/src/main/java/org/elasticsearch/index/mapper/internal/AllFieldMapper.java index cfd5df6e28fb3..16cdb6e3ea74f 100644 --- a/src/main/java/org/elasticsearch/index/mapper/internal/AllFieldMapper.java +++ b/src/main/java/org/elasticsearch/index/mapper/internal/AllFieldMapper.java @@ -46,6 +46,7 @@ import org.elasticsearch.index.similarity.SimilarityProvider; import java.io.IOException; +import java.util.Iterator; import java.util.List; import java.util.Map; @@ -121,13 +122,16 @@ public static class TypeParser implements Mapper.TypeParser { public Mapper.Builder parse(String name, Map node, ParserContext parserContext) throws MapperParsingException { AllFieldMapper.Builder builder = all(); parseField(builder, builder.name, node, parserContext); - for (Map.Entry entry : node.entrySet()) { + for (Iterator> iterator = node.entrySet().iterator(); iterator.hasNext();) { + Map.Entry entry = iterator.next(); String fieldName = Strings.toUnderscoreCase(entry.getKey()); Object fieldNode = entry.getValue(); if (fieldName.equals("enabled")) { builder.enabled(nodeBooleanValue(fieldNode)); + iterator.remove(); } else if (fieldName.equals("auto_boost")) { builder.autoBoost = nodeBooleanValue(fieldNode); + iterator.remove(); } } return builder; diff --git a/src/main/java/org/elasticsearch/index/mapper/internal/AnalyzerMapper.java b/src/main/java/org/elasticsearch/index/mapper/internal/AnalyzerMapper.java index dffe9a93b4be8..a70c13fafa60a 100644 --- a/src/main/java/org/elasticsearch/index/mapper/internal/AnalyzerMapper.java +++ b/src/main/java/org/elasticsearch/index/mapper/internal/AnalyzerMapper.java @@ -27,6 +27,7 @@ import org.elasticsearch.search.highlight.HighlighterContext; import java.io.IOException; +import java.util.Iterator; import java.util.List; import java.util.Map; @@ -68,11 +69,13 @@ public static class TypeParser implements Mapper.TypeParser { @Override public Mapper.Builder parse(String name, Map node, ParserContext parserContext) throws MapperParsingException { AnalyzerMapper.Builder builder = analyzer(); - for (Map.Entry entry : node.entrySet()) { + for (Iterator> iterator = node.entrySet().iterator(); iterator.hasNext();) { + Map.Entry entry = iterator.next(); String fieldName = Strings.toUnderscoreCase(entry.getKey()); Object fieldNode = entry.getValue(); if (fieldName.equals("path")) { builder.field(fieldNode.toString()); + iterator.remove(); } } return builder; diff --git a/src/main/java/org/elasticsearch/index/mapper/internal/BoostFieldMapper.java b/src/main/java/org/elasticsearch/index/mapper/internal/BoostFieldMapper.java index 1963bd12fe666..3b7be73ee3f75 100644 --- a/src/main/java/org/elasticsearch/index/mapper/internal/BoostFieldMapper.java +++ b/src/main/java/org/elasticsearch/index/mapper/internal/BoostFieldMapper.java @@ -48,6 +48,7 @@ import org.elasticsearch.index.search.NumericRangeFieldDataFilter; import java.io.IOException; +import java.util.Iterator; import java.util.List; import java.util.Map; @@ -103,14 +104,16 @@ public BoostFieldMapper build(BuilderContext context) { 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(); + String name = node.get("name") == null ? BoostFieldMapper.Defaults.NAME : node.remove("name").toString(); BoostFieldMapper.Builder builder = MapperBuilders.boost(name); parseNumberField(builder, name, node, parserContext); - for (Map.Entry entry : node.entrySet()) { + for (Iterator> iterator = node.entrySet().iterator(); iterator.hasNext();) { + Map.Entry entry = iterator.next(); String propName = Strings.toUnderscoreCase(entry.getKey()); Object propNode = entry.getValue(); if (propName.equals("null_value")) { builder.nullValue(nodeFloatValue(propNode)); + iterator.remove(); } } return builder; diff --git a/src/main/java/org/elasticsearch/index/mapper/internal/IdFieldMapper.java b/src/main/java/org/elasticsearch/index/mapper/internal/IdFieldMapper.java index d0bdc30a5ed75..e5c5e14efa451 100644 --- a/src/main/java/org/elasticsearch/index/mapper/internal/IdFieldMapper.java +++ b/src/main/java/org/elasticsearch/index/mapper/internal/IdFieldMapper.java @@ -50,6 +50,7 @@ import java.io.IOException; import java.util.Collection; +import java.util.Iterator; import java.util.List; import java.util.Map; @@ -110,11 +111,13 @@ public static class TypeParser implements Mapper.TypeParser { public Mapper.Builder parse(String name, Map node, ParserContext parserContext) throws MapperParsingException { IdFieldMapper.Builder builder = id(); parseField(builder, builder.name, node, parserContext); - for (Map.Entry entry : node.entrySet()) { + for (Iterator> iterator = node.entrySet().iterator(); iterator.hasNext();) { + Map.Entry entry = iterator.next(); String fieldName = Strings.toUnderscoreCase(entry.getKey()); Object fieldNode = entry.getValue(); if (fieldName.equals("path")) { builder.path(fieldNode.toString()); + iterator.remove(); } } return builder; diff --git a/src/main/java/org/elasticsearch/index/mapper/internal/IndexFieldMapper.java b/src/main/java/org/elasticsearch/index/mapper/internal/IndexFieldMapper.java index 38e1e97a3a7ae..74c23e0a1eae4 100644 --- a/src/main/java/org/elasticsearch/index/mapper/internal/IndexFieldMapper.java +++ b/src/main/java/org/elasticsearch/index/mapper/internal/IndexFieldMapper.java @@ -36,6 +36,7 @@ import org.elasticsearch.index.mapper.core.AbstractFieldMapper; import java.io.IOException; +import java.util.Iterator; import java.util.List; import java.util.Map; @@ -94,12 +95,14 @@ public Mapper.Builder parse(String name, Map node, ParserContext IndexFieldMapper.Builder builder = MapperBuilders.index(); parseField(builder, builder.name, node, parserContext); - for (Map.Entry entry : node.entrySet()) { + for (Iterator> iterator = node.entrySet().iterator(); iterator.hasNext();) { + Map.Entry entry = iterator.next(); String fieldName = Strings.toUnderscoreCase(entry.getKey()); Object fieldNode = entry.getValue(); if (fieldName.equals("enabled")) { EnabledAttributeMapper mapper = nodeBooleanValue(fieldNode) ? EnabledAttributeMapper.ENABLED : EnabledAttributeMapper.DISABLED; builder.enabled(mapper); + iterator.remove(); } } return builder; diff --git a/src/main/java/org/elasticsearch/index/mapper/internal/ParentFieldMapper.java b/src/main/java/org/elasticsearch/index/mapper/internal/ParentFieldMapper.java index fa9d4df31a626..19b4b9384d55f 100644 --- a/src/main/java/org/elasticsearch/index/mapper/internal/ParentFieldMapper.java +++ b/src/main/java/org/elasticsearch/index/mapper/internal/ParentFieldMapper.java @@ -45,6 +45,7 @@ import java.io.IOException; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; import java.util.Map; @@ -119,14 +120,17 @@ public static class TypeParser implements Mapper.TypeParser { @Override public Mapper.Builder parse(String name, Map node, ParserContext parserContext) throws MapperParsingException { ParentFieldMapper.Builder builder = parent(); - for (Map.Entry entry : node.entrySet()) { + for (Iterator> iterator = node.entrySet().iterator(); iterator.hasNext();) { + Map.Entry entry = iterator.next(); String fieldName = Strings.toUnderscoreCase(entry.getKey()); Object fieldNode = entry.getValue(); if (fieldName.equals("type")) { builder.type(fieldNode.toString()); + iterator.remove(); } else if (fieldName.equals("postings_format")) { String postingFormatName = fieldNode.toString(); builder.postingsFormat(parserContext.postingFormatService().get(postingFormatName)); + iterator.remove(); } else if (fieldName.equals("fielddata")) { // Only take over `loading`, since that is the only option now that is configurable: Map fieldDataSettings = SettingsLoader.Helper.loadNestedFromMap(nodeMapValue(fieldNode, "fielddata")); @@ -134,6 +138,7 @@ public Mapper.Builder parse(String name, Map node, ParserContext Settings settings = settingsBuilder().put(Loading.KEY, fieldDataSettings.get(Loading.KEY)).build(); builder.fieldDataSettings(settings); } + iterator.remove(); } } return builder; diff --git a/src/main/java/org/elasticsearch/index/mapper/internal/RoutingFieldMapper.java b/src/main/java/org/elasticsearch/index/mapper/internal/RoutingFieldMapper.java index 25f61ebac8fa5..4e33c5b7297a5 100644 --- a/src/main/java/org/elasticsearch/index/mapper/internal/RoutingFieldMapper.java +++ b/src/main/java/org/elasticsearch/index/mapper/internal/RoutingFieldMapper.java @@ -36,6 +36,7 @@ import org.elasticsearch.index.mapper.core.AbstractFieldMapper; import java.io.IOException; +import java.util.Iterator; import java.util.List; import java.util.Map; @@ -99,13 +100,16 @@ public static class TypeParser implements Mapper.TypeParser { 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()) { + for (Iterator> iterator = node.entrySet().iterator(); iterator.hasNext();) { + Map.Entry entry = iterator.next(); String fieldName = Strings.toUnderscoreCase(entry.getKey()); Object fieldNode = entry.getValue(); if (fieldName.equals("required")) { builder.required(nodeBooleanValue(fieldNode)); + iterator.remove(); } else if (fieldName.equals("path")) { builder.path(fieldNode.toString()); + iterator.remove(); } } return builder; diff --git a/src/main/java/org/elasticsearch/index/mapper/internal/SizeFieldMapper.java b/src/main/java/org/elasticsearch/index/mapper/internal/SizeFieldMapper.java index ca46ea16e40ef..254baebe5d1c1 100644 --- a/src/main/java/org/elasticsearch/index/mapper/internal/SizeFieldMapper.java +++ b/src/main/java/org/elasticsearch/index/mapper/internal/SizeFieldMapper.java @@ -33,6 +33,7 @@ import org.elasticsearch.index.mapper.core.NumberFieldMapper; import java.io.IOException; +import java.util.Iterator; import java.util.List; import java.util.Map; @@ -80,13 +81,16 @@ public static class TypeParser implements Mapper.TypeParser { @Override public Mapper.Builder parse(String name, Map node, ParserContext parserContext) throws MapperParsingException { SizeFieldMapper.Builder builder = size(); - for (Map.Entry entry : node.entrySet()) { + for (Iterator> iterator = node.entrySet().iterator(); iterator.hasNext();) { + Map.Entry entry = iterator.next(); String fieldName = Strings.toUnderscoreCase(entry.getKey()); Object fieldNode = entry.getValue(); if (fieldName.equals("enabled")) { builder.enabled(nodeBooleanValue(fieldNode) ? EnabledAttributeMapper.ENABLED : EnabledAttributeMapper.DISABLED); + iterator.remove(); } else if (fieldName.equals("store")) { builder.store(parseStore(fieldName, fieldNode.toString())); + iterator.remove(); } } return builder; diff --git a/src/main/java/org/elasticsearch/index/mapper/internal/SourceFieldMapper.java b/src/main/java/org/elasticsearch/index/mapper/internal/SourceFieldMapper.java index 756dc0514c570..60f85225531dc 100644 --- a/src/main/java/org/elasticsearch/index/mapper/internal/SourceFieldMapper.java +++ b/src/main/java/org/elasticsearch/index/mapper/internal/SourceFieldMapper.java @@ -48,6 +48,7 @@ import org.elasticsearch.index.mapper.core.AbstractFieldMapper; import java.io.IOException; +import java.util.Iterator; import java.util.List; import java.util.Map; @@ -139,23 +140,32 @@ public static class TypeParser implements Mapper.TypeParser { public Mapper.Builder parse(String name, Map node, ParserContext parserContext) throws MapperParsingException { SourceFieldMapper.Builder builder = source(); - for (Map.Entry entry : node.entrySet()) { + for (Iterator> iterator = node.entrySet().iterator(); iterator.hasNext();) { + Map.Entry entry = iterator.next(); String fieldName = Strings.toUnderscoreCase(entry.getKey()); Object fieldNode = entry.getValue(); if (fieldName.equals("enabled")) { builder.enabled(nodeBooleanValue(fieldNode)); - } else if (fieldName.equals("compress") && fieldNode != null) { - builder.compress(nodeBooleanValue(fieldNode)); - } else if (fieldName.equals("compress_threshold") && fieldNode != null) { - if (fieldNode instanceof Number) { - builder.compressThreshold(((Number) fieldNode).longValue()); - builder.compress(true); - } else { - builder.compressThreshold(ByteSizeValue.parseBytesSizeValue(fieldNode.toString()).bytes()); - builder.compress(true); + iterator.remove(); + } else if (fieldName.equals("compress")) { + if (fieldNode != null) { + builder.compress(nodeBooleanValue(fieldNode)); } + iterator.remove(); + } else if (fieldName.equals("compress_threshold")) { + if (fieldNode != null) { + if (fieldNode instanceof Number) { + builder.compressThreshold(((Number) fieldNode).longValue()); + builder.compress(true); + } else { + builder.compressThreshold(ByteSizeValue.parseBytesSizeValue(fieldNode.toString()).bytes()); + builder.compress(true); + } + } + iterator.remove(); } else if ("format".equals(fieldName)) { builder.format(nodeStringValue(fieldNode, null)); + iterator.remove(); } else if (fieldName.equals("includes")) { List values = (List) fieldNode; String[] includes = new String[values.size()]; @@ -163,6 +173,7 @@ public Mapper.Builder parse(String name, Map node, ParserContext includes[i] = values.get(i).toString(); } builder.includes(includes); + iterator.remove(); } else if (fieldName.equals("excludes")) { List values = (List) fieldNode; String[] excludes = new String[values.size()]; @@ -170,6 +181,7 @@ public Mapper.Builder parse(String name, Map node, ParserContext excludes[i] = values.get(i).toString(); } builder.excludes(excludes); + iterator.remove(); } } return builder; diff --git a/src/main/java/org/elasticsearch/index/mapper/internal/TTLFieldMapper.java b/src/main/java/org/elasticsearch/index/mapper/internal/TTLFieldMapper.java index 9af9480b90f0d..432799a3c7ffd 100644 --- a/src/main/java/org/elasticsearch/index/mapper/internal/TTLFieldMapper.java +++ b/src/main/java/org/elasticsearch/index/mapper/internal/TTLFieldMapper.java @@ -39,6 +39,7 @@ import java.io.IOException; import java.util.Date; +import java.util.Iterator; import java.util.List; import java.util.Map; @@ -98,17 +99,20 @@ public static class TypeParser implements Mapper.TypeParser { public Mapper.Builder parse(String name, Map node, ParserContext parserContext) throws MapperParsingException { TTLFieldMapper.Builder builder = ttl(); parseField(builder, builder.name, node, parserContext); - for (Map.Entry entry : node.entrySet()) { + for (Iterator> iterator = node.entrySet().iterator(); iterator.hasNext();) { + Map.Entry entry = iterator.next(); String fieldName = Strings.toUnderscoreCase(entry.getKey()); Object fieldNode = entry.getValue(); if (fieldName.equals("enabled")) { EnabledAttributeMapper enabledState = nodeBooleanValue(fieldNode) ? EnabledAttributeMapper.ENABLED : EnabledAttributeMapper.DISABLED; builder.enabled(enabledState); + iterator.remove(); } else if (fieldName.equals("default")) { TimeValue ttlTimeValue = nodeTimeValue(fieldNode, null); if (ttlTimeValue != null) { builder.defaultTTL(ttlTimeValue.millis()); } + iterator.remove(); } } return builder; diff --git a/src/main/java/org/elasticsearch/index/mapper/internal/TimestampFieldMapper.java b/src/main/java/org/elasticsearch/index/mapper/internal/TimestampFieldMapper.java index 8c7effbe77b03..95242524fe9b1 100644 --- a/src/main/java/org/elasticsearch/index/mapper/internal/TimestampFieldMapper.java +++ b/src/main/java/org/elasticsearch/index/mapper/internal/TimestampFieldMapper.java @@ -39,6 +39,7 @@ import org.elasticsearch.index.mapper.core.NumberFieldMapper; import java.io.IOException; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; @@ -137,18 +138,23 @@ public static class TypeParser implements Mapper.TypeParser { public Mapper.Builder parse(String name, Map node, ParserContext parserContext) throws MapperParsingException { TimestampFieldMapper.Builder builder = timestamp(); parseField(builder, builder.name, node, parserContext); - for (Map.Entry entry : node.entrySet()) { + for (Iterator> iterator = node.entrySet().iterator(); iterator.hasNext();) { + Map.Entry entry = iterator.next(); String fieldName = Strings.toUnderscoreCase(entry.getKey()); Object fieldNode = entry.getValue(); if (fieldName.equals("enabled")) { EnabledAttributeMapper enabledState = nodeBooleanValue(fieldNode) ? EnabledAttributeMapper.ENABLED : EnabledAttributeMapper.DISABLED; builder.enabled(enabledState); + iterator.remove(); } else if (fieldName.equals("path")) { builder.path(fieldNode.toString()); + iterator.remove(); } else if (fieldName.equals("format")) { builder.dateTimeFormatter(parseDateTimeFormatter(fieldNode.toString())); + iterator.remove(); } else if (fieldName.equals("default")) { builder.defaultTimestamp(fieldNode == null ? null : fieldNode.toString()); + iterator.remove(); } } return builder; diff --git a/src/main/java/org/elasticsearch/index/mapper/internal/VersionFieldMapper.java b/src/main/java/org/elasticsearch/index/mapper/internal/VersionFieldMapper.java index 4aac10e7526ae..a603e07c528f7 100644 --- a/src/main/java/org/elasticsearch/index/mapper/internal/VersionFieldMapper.java +++ b/src/main/java/org/elasticsearch/index/mapper/internal/VersionFieldMapper.java @@ -33,6 +33,7 @@ import org.elasticsearch.index.mapper.core.AbstractFieldMapper; import java.io.IOException; +import java.util.Iterator; import java.util.List; import java.util.Map; @@ -75,12 +76,14 @@ public static class TypeParser implements Mapper.TypeParser { @Override public Mapper.Builder parse(String name, Map node, ParserContext parserContext) throws MapperParsingException { Builder builder = version(); - for (Map.Entry entry : node.entrySet()) { + for (Iterator> iterator = node.entrySet().iterator(); iterator.hasNext();) { + Map.Entry entry = iterator.next(); String fieldName = Strings.toUnderscoreCase(entry.getKey()); Object fieldNode = entry.getValue(); if (fieldName.equals(DOC_VALUES_FORMAT)) { String docValuesFormatName = fieldNode.toString(); builder.docValuesFormat(parserContext.docValuesFormatService().get(docValuesFormatName)); + iterator.remove(); } } return builder; diff --git a/src/main/java/org/elasticsearch/index/mapper/ip/IpFieldMapper.java b/src/main/java/org/elasticsearch/index/mapper/ip/IpFieldMapper.java index 25d76304b2a4a..215beae038ac7 100644 --- a/src/main/java/org/elasticsearch/index/mapper/ip/IpFieldMapper.java +++ b/src/main/java/org/elasticsearch/index/mapper/ip/IpFieldMapper.java @@ -55,6 +55,7 @@ import org.elasticsearch.index.similarity.SimilarityProvider; import java.io.IOException; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.regex.Pattern; @@ -139,7 +140,8 @@ public static class TypeParser implements Mapper.TypeParser { public Mapper.Builder parse(String name, Map node, ParserContext parserContext) throws MapperParsingException { IpFieldMapper.Builder builder = ipField(name); parseNumberField(builder, name, node, parserContext); - for (Map.Entry entry : node.entrySet()) { + for (Iterator> iterator = node.entrySet().iterator(); iterator.hasNext();) { + Map.Entry entry = iterator.next(); String propName = Strings.toUnderscoreCase(entry.getKey()); Object propNode = entry.getValue(); if (propName.equals("null_value")) { @@ -147,6 +149,7 @@ public Mapper.Builder parse(String name, Map node, ParserContext throw new MapperParsingException("Property [null_value] cannot be null."); } builder.nullValue(propNode.toString()); + iterator.remove(); } } return builder; diff --git a/src/main/java/org/elasticsearch/index/mapper/object/ObjectMapper.java b/src/main/java/org/elasticsearch/index/mapper/object/ObjectMapper.java index bfafa5212d008..2c681f816e325 100644 --- a/src/main/java/org/elasticsearch/index/mapper/object/ObjectMapper.java +++ b/src/main/java/org/elasticsearch/index/mapper/object/ObjectMapper.java @@ -36,19 +36,48 @@ import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentParser; -import org.elasticsearch.index.mapper.*; +import org.elasticsearch.index.mapper.ContentPath; +import org.elasticsearch.index.mapper.DocumentMapperParser; +import org.elasticsearch.index.mapper.FieldMapper; +import org.elasticsearch.index.mapper.FieldMapperListener; +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.ObjectMapperListener; +import org.elasticsearch.index.mapper.ParseContext; import org.elasticsearch.index.mapper.ParseContext.Document; +import org.elasticsearch.index.mapper.StrictDynamicMappingException; import org.elasticsearch.index.mapper.internal.AllFieldMapper; import org.elasticsearch.index.mapper.internal.TypeFieldMapper; import org.elasticsearch.index.mapper.internal.UidFieldMapper; import org.elasticsearch.index.settings.IndexSettings; import java.io.IOException; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.TreeMap; import static com.google.common.collect.Lists.newArrayList; import static org.elasticsearch.common.xcontent.support.XContentMapValues.nodeBooleanValue; -import static org.elasticsearch.index.mapper.MapperBuilders.*; +import static org.elasticsearch.index.mapper.MapperBuilders.binaryField; +import static org.elasticsearch.index.mapper.MapperBuilders.booleanField; +import static org.elasticsearch.index.mapper.MapperBuilders.dateField; +import static org.elasticsearch.index.mapper.MapperBuilders.doubleField; +import static org.elasticsearch.index.mapper.MapperBuilders.floatField; +import static org.elasticsearch.index.mapper.MapperBuilders.integerField; +import static org.elasticsearch.index.mapper.MapperBuilders.longField; +import static org.elasticsearch.index.mapper.MapperBuilders.object; +import static org.elasticsearch.index.mapper.MapperBuilders.stringField; import static org.elasticsearch.index.mapper.core.TypeParsers.parsePathType; /** @@ -183,13 +212,15 @@ public static class TypeParser implements Mapper.TypeParser { @Override public Mapper.Builder parse(String name, Map node, ParserContext parserContext) throws MapperParsingException { ObjectMapper.Builder builder = createBuilder(name); - for (Map.Entry entry : node.entrySet()) { + parseNested(name, node, builder); + for (Iterator> iterator = node.entrySet().iterator(); iterator.hasNext();) { + Map.Entry entry = iterator.next(); String fieldName = Strings.toUnderscoreCase(entry.getKey()); Object fieldNode = entry.getValue(); - parseObjectOrDocumentTypeProperties(fieldName, fieldNode, parserContext, builder); - parseObjectProperties(name, fieldName, fieldNode, builder); + if (parseObjectOrDocumentTypeProperties(fieldName, fieldNode, parserContext, builder) || parseObjectProperties(name, fieldName, fieldNode, builder)) { + iterator.remove(); + } } - parseNested(name, node, builder); return builder; } @@ -221,10 +252,12 @@ protected static boolean parseObjectOrDocumentTypeProperties(String fieldName, O return false; } - protected static void parseObjectProperties(String name, String fieldName, Object fieldNode, ObjectMapper.Builder builder) { - if (fieldName.equals("path")) { + protected static boolean parseObjectProperties(String name, String fieldName, Object fieldNode, ObjectMapper.Builder builder) { + if (fieldName.equals("path")) { builder.pathType(parsePathType(name, fieldNode.toString())); + return true; } + return false; } protected static void parseNested(String name, Map node, ObjectMapper.Builder builder) { @@ -245,10 +278,12 @@ protected static void parseNested(String name, Map node, ObjectM fieldNode = node.get("include_in_parent"); if (fieldNode != null) { nestedIncludeInParent = nodeBooleanValue(fieldNode); + node.remove("include_in_parent"); } fieldNode = node.get("include_in_root"); if (fieldNode != null) { nestedIncludeInRoot = nodeBooleanValue(fieldNode); + node.remove("include_in_root"); } if (nested) { builder.nested = Nested.newNested(nestedIncludeInParent, nestedIncludeInRoot); @@ -257,12 +292,15 @@ protected static void parseNested(String name, Map node, ObjectM } protected static void parseProperties(ObjectMapper.Builder objBuilder, Map propsNode, ParserContext parserContext) { - for (Map.Entry entry : propsNode.entrySet()) { + Iterator> iterator = propsNode.entrySet().iterator(); + while (iterator.hasNext()) { + Map.Entry entry = iterator.next(); String propName = entry.getKey(); - //Should accept empty arrays, as a work around for when the user can't provide an empty Map. (PHP for example) + // Should accept empty arrays, as a work around for when the + // user can't provide an empty Map. (PHP for example) boolean isEmptyList = entry.getValue() instanceof List && ((List) entry.getValue()).isEmpty(); - if (entry.getValue() instanceof Map) { + if (entry.getValue() instanceof Map) { @SuppressWarnings("unchecked") Map propNode = (Map) entry.getValue(); String type; @@ -274,9 +312,10 @@ protected static void parseProperties(ObjectMapper.Builder objBuilder, Map co if (fieldName != null) { mapping.fieldName(fieldName.toString()); + config.remove(FIELD_FIELDNAME); } if (defaultValues != null) { @@ -133,6 +134,7 @@ protected static CategoryContextMapping load(String name, Map co } else { mapping.addDefaultValue(defaultValues.toString()); } + config.remove(FIELD_MISSING); } return mapping.build(); diff --git a/src/main/java/org/elasticsearch/search/suggest/context/ContextBuilder.java b/src/main/java/org/elasticsearch/search/suggest/context/ContextBuilder.java index dde313615f158..201625b613981 100644 --- a/src/main/java/org/elasticsearch/search/suggest/context/ContextBuilder.java +++ b/src/main/java/org/elasticsearch/search/suggest/context/ContextBuilder.java @@ -21,6 +21,8 @@ import com.google.common.collect.Maps; import org.elasticsearch.ElasticsearchParseException; +import org.elasticsearch.Version; +import org.elasticsearch.index.mapper.DocumentMapperParser; import java.util.Map; import java.util.Map.Entry; @@ -91,13 +93,14 @@ public static CategoryContextMapping.Builder reference(String name, String field return new CategoryContextMapping.Builder(name, fieldname).addDefaultValues(defaultValues); } - public static SortedMap loadMappings(Object configuration) throws ElasticsearchParseException { + public static SortedMap loadMappings(Object configuration, Version indexVersionCreated) + throws ElasticsearchParseException { if (configuration instanceof Map) { Map configurations = (Map)configuration; SortedMap mappings = Maps.newTreeMap(); for (Entry config : configurations.entrySet()) { String name = config.getKey(); - mappings.put(name, loadMapping(name, (Map) config.getValue())); + mappings.put(name, loadMapping(name, (Map) config.getValue(), indexVersionCreated)); } return mappings; } else if (configuration == null) { @@ -107,7 +110,8 @@ public static SortedMap loadMappings(Object configuratio } } - protected static ContextMapping loadMapping(String name, Map config) throws ElasticsearchParseException { + protected static ContextMapping loadMapping(String name, Map config, Version indexVersionCreated) + throws ElasticsearchParseException { final Object argType = config.get(ContextMapping.FIELD_TYPE); if (argType == null) { @@ -115,13 +119,17 @@ protected static ContextMapping loadMapping(String name, Map con } final String type = argType.toString(); - + ContextMapping contextMapping; if (GeolocationContextMapping.TYPE.equals(type)) { - return GeolocationContextMapping.load(name, config); + contextMapping = GeolocationContextMapping.load(name, config); } else if (CategoryContextMapping.TYPE.equals(type)) { - return CategoryContextMapping.load(name, config); + contextMapping = CategoryContextMapping.load(name, config); } else { throw new ElasticsearchParseException("unknown context type[" + type + "]"); } + config.remove(ContextMapping.FIELD_TYPE); + DocumentMapperParser.checkNoRemainingFields(name, config, indexVersionCreated); + + return contextMapping; } } diff --git a/src/main/java/org/elasticsearch/search/suggest/context/GeolocationContextMapping.java b/src/main/java/org/elasticsearch/search/suggest/context/GeolocationContextMapping.java index 0506d7f145e2d..d7c026a3b77c5 100644 --- a/src/main/java/org/elasticsearch/search/suggest/context/GeolocationContextMapping.java +++ b/src/main/java/org/elasticsearch/search/suggest/context/GeolocationContextMapping.java @@ -127,12 +127,16 @@ protected static GeolocationContextMapping load(String name, Map // ignore precision } else if (configPrecision instanceof Integer) { builder.precision((Integer) configPrecision); + config.remove(FIELD_PRECISION); } else if (configPrecision instanceof Long) { builder.precision((Long) configPrecision); + config.remove(FIELD_PRECISION); } else if (configPrecision instanceof Double) { builder.precision((Double) configPrecision); + config.remove(FIELD_PRECISION); } else if (configPrecision instanceof Float) { builder.precision((Float) configPrecision); + config.remove(FIELD_PRECISION); } else if (configPrecision instanceof Iterable) { for (Object precision : (Iterable)configPrecision) { if (precision instanceof Integer) { @@ -147,13 +151,16 @@ protected static GeolocationContextMapping load(String name, Map builder.precision(precision.toString()); } } + config.remove(FIELD_PRECISION); } else { builder.precision(configPrecision.toString()); + config.remove(FIELD_PRECISION); } final Object configNeighbors = config.get(FIELD_NEIGHBORS); if (configNeighbors != null) { builder.neighbors((Boolean) configNeighbors); + config.remove(FIELD_NEIGHBORS); } final Object def = config.get(FIELD_MISSING); @@ -176,11 +183,13 @@ protected static GeolocationContextMapping load(String name, Map } else { throw new ElasticsearchParseException("field [" + FIELD_MISSING + "] must be of type string or list"); } + config.remove(FIELD_MISSING); } final Object fieldName = config.get(FIELD_FIELDNAME); if (fieldName != null) { builder.field(fieldName.toString()); + config.remove(FIELD_FIELDNAME); } } return builder.build(); diff --git a/src/test/java/org/elasticsearch/get/GetActionTests.java b/src/test/java/org/elasticsearch/get/GetActionTests.java index d43c8dbe2ee72..6b93448f7c0fb 100644 --- a/src/test/java/org/elasticsearch/get/GetActionTests.java +++ b/src/test/java/org/elasticsearch/get/GetActionTests.java @@ -473,7 +473,7 @@ public void testThatGetFromTranslogShouldWorkWithIncludeExcludeAndFields() throw .startObject(type) .startObject("_source") .array("includes", "included") - .array("exlcudes", "excluded") + .array("excludes", "excluded") .endObject() .endObject() .endObject() @@ -806,13 +806,13 @@ public void testGetFields_complexField() throws Exception { assertAcked(prepareCreate("my-index") .setSettings(ImmutableSettings.settingsBuilder().put("index.refresh_interval", -1)) .addMapping("my-type2", jsonBuilder().startObject().startObject("my-type2").startObject("properties") - .startObject("field1").field("type", "object") - .startObject("field2").field("type", "object") - .startObject("field3").field("type", "object") + .startObject("field1").field("type", "object").startObject("properties") + .startObject("field2").field("type", "object").startObject("properties") + .startObject("field3").field("type", "object").startObject("properties") .startObject("field4").field("type", "string").field("store", "yes") - .endObject() - .endObject() - .endObject() + .endObject().endObject() + .endObject().endObject() + .endObject().endObject() .endObject().endObject().endObject())); BytesReference source = jsonBuilder().startObject() @@ -977,8 +977,7 @@ public void testUngeneratedFieldsThatAreAlwaysStored() throws IOException { " \"enabled\": " + randomBoolean() + "\n" + " },\n" + " \"_parent\": {\n" + - " \"type\": \"parentdoc\",\n" + - " \"store\": \"" + storedString + "\"\n" + + " \"type\": \"parentdoc\"\n" + " },\n" + " \"_ttl\": {\n" + " \"enabled\": true,\n" + diff --git a/src/test/java/org/elasticsearch/index/mapper/externalvalues/ExternalMapper.java b/src/test/java/org/elasticsearch/index/mapper/externalvalues/ExternalMapper.java index 4e75706ddceef..3b8dd2e8d9ede 100755 --- a/src/test/java/org/elasticsearch/index/mapper/externalvalues/ExternalMapper.java +++ b/src/test/java/org/elasticsearch/index/mapper/externalvalues/ExternalMapper.java @@ -37,6 +37,7 @@ import java.io.IOException; import java.nio.charset.Charset; +import java.util.Iterator; import java.util.List; import java.util.Map; @@ -127,11 +128,14 @@ public static class TypeParser implements Mapper.TypeParser { public Mapper.Builder parse(String name, Map node, ParserContext parserContext) throws MapperParsingException { ExternalMapper.Builder builder = new ExternalMapper.Builder(name, generatedValue, mapperName); parseField(builder, name, node, parserContext); - for (Map.Entry entry : node.entrySet()) { + for (Iterator> iterator = node.entrySet().iterator(); iterator.hasNext();) { + Map.Entry entry = iterator.next(); String propName = Strings.toUnderscoreCase(entry.getKey()); Object propNode = entry.getValue(); - parseMultiField(builder, name, parserContext, propName, propNode); + if (parseMultiField(builder, name, parserContext, propName, propNode)) { + iterator.remove(); + } } return builder; diff --git a/src/test/java/org/elasticsearch/index/mapper/externalvalues/ExternalValuesMapperIntegrationTests.java b/src/test/java/org/elasticsearch/index/mapper/externalvalues/ExternalValuesMapperIntegrationTests.java index 86953beddd4c9..43c008c81dd04 100644 --- a/src/test/java/org/elasticsearch/index/mapper/externalvalues/ExternalValuesMapperIntegrationTests.java +++ b/src/test/java/org/elasticsearch/index/mapper/externalvalues/ExternalValuesMapperIntegrationTests.java @@ -99,12 +99,12 @@ public void testExternalValuesWithMultifield() throws Exception { .startObject("fields") .startObject("f") .field("type", "string") - .field("stored", "yes") + .field("store", "yes") .startObject("fields") .startObject("raw") .field("type", "string") .field("index", "not_analyzed") - .field("stored", "yes") + .field("store", "yes") .endObject() .endObject() .endObject() diff --git a/src/test/java/org/elasticsearch/index/mapper/externalvalues/SimpleExternalMappingTests.java b/src/test/java/org/elasticsearch/index/mapper/externalvalues/SimpleExternalMappingTests.java index d9765dcb96b13..f48dd286e0cf1 100644 --- a/src/test/java/org/elasticsearch/index/mapper/externalvalues/SimpleExternalMappingTests.java +++ b/src/test/java/org/elasticsearch/index/mapper/externalvalues/SimpleExternalMappingTests.java @@ -85,12 +85,12 @@ public void testExternalValuesWithMultifield() throws Exception { .startObject("fields") .startObject("field") .field("type", "string") - .field("stored", "yes") + .field("store", "yes") .startObject("fields") .startObject("raw") .field("type", "string") .field("index", "not_analyzed") - .field("stored", "yes") + .field("store", "yes") .endObject() .endObject() .endObject() diff --git a/src/test/java/org/elasticsearch/index/mapper/simple/test-mapping.json b/src/test/java/org/elasticsearch/index/mapper/simple/test-mapping.json index d45d55704a132..3d7516fa2dbf1 100644 --- a/src/test/java/org/elasticsearch/index/mapper/simple/test-mapping.json +++ b/src/test/java/org/elasticsearch/index/mapper/simple/test-mapping.json @@ -7,17 +7,13 @@ dynamic:false, enabled:true, _id:{ - name:"_id", index_name:"_id" }, _source:{ - name:"_source" }, _type:{ - name:"_type" }, _boost:{ - name:"_boost", null_value:2.0 }, properties:{ diff --git a/src/test/java/org/elasticsearch/percolator/PercolatorTests.java b/src/test/java/org/elasticsearch/percolator/PercolatorTests.java index cfe2844a898be..30180914675c9 100644 --- a/src/test/java/org/elasticsearch/percolator/PercolatorTests.java +++ b/src/test/java/org/elasticsearch/percolator/PercolatorTests.java @@ -53,17 +53,50 @@ import org.junit.Test; import java.io.IOException; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.NavigableSet; +import java.util.Set; +import java.util.TreeSet; import static org.elasticsearch.action.percolate.PercolateSourceBuilder.docBuilder; import static org.elasticsearch.common.settings.ImmutableSettings.builder; import static org.elasticsearch.common.settings.ImmutableSettings.settingsBuilder; -import static org.elasticsearch.common.xcontent.XContentFactory.*; +import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder; +import static org.elasticsearch.common.xcontent.XContentFactory.smileBuilder; +import static org.elasticsearch.common.xcontent.XContentFactory.yamlBuilder; import static org.elasticsearch.index.query.FilterBuilders.termFilter; -import static org.elasticsearch.index.query.QueryBuilders.*; +import static org.elasticsearch.index.query.QueryBuilders.boolQuery; +import static org.elasticsearch.index.query.QueryBuilders.constantScoreQuery; +import static org.elasticsearch.index.query.QueryBuilders.functionScoreQuery; +import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery; +import static org.elasticsearch.index.query.QueryBuilders.matchQuery; +import static org.elasticsearch.index.query.QueryBuilders.rangeQuery; +import static org.elasticsearch.index.query.QueryBuilders.termQuery; import static org.elasticsearch.index.query.functionscore.ScoreFunctionBuilders.scriptFunction; -import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.*; -import static org.hamcrest.Matchers.*; +import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked; +import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAllSuccessful; +import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCount; +import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertMatchCount; +import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertNoFailures; +import static org.hamcrest.Matchers.anyOf; +import static org.hamcrest.Matchers.arrayContaining; +import static org.hamcrest.Matchers.arrayContainingInAnyOrder; +import static org.hamcrest.Matchers.arrayWithSize; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.emptyArray; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.greaterThan; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.hamcrest.Matchers.nullValue; /** * @@ -525,7 +558,8 @@ public void dynamicAddingRemovingQueries() throws Exception { @Test public void percolateWithSizeField() throws Exception { String mapping = XContentFactory.jsonBuilder().startObject().startObject("type1") - .startObject("_size").field("enabled", true).field("stored", "yes").endObject() +.startObject("_size").field("enabled", true) + .field("store", "yes").endObject() .startObject("properties").startObject("field1").field("type", "string").endObject().endObject() .endObject().endObject().string(); @@ -1678,7 +1712,7 @@ public void testPercolationWithDynamicTemplates() throws Exception { .startObject("custom") .field("dynamic", true) .field("type", "object") - .field("incude_in_all", false) + .field("include_in_all", false) .endObject() .endObject() .startArray("dynamic_templates") @@ -1695,9 +1729,9 @@ public void testPercolationWithDynamicTemplates() throws Exception { ensureGreen("idx"); try { - client().prepareIndex("idx", PercolatorService.TYPE_NAME, "1") - .setSource(jsonBuilder().startObject().field("query", QueryBuilders.queryString("color:red")).endObject()) - .get(); + client().prepareIndex("idx", PercolatorService.TYPE_NAME, "1") + .setSource(jsonBuilder().startObject().field("query", QueryBuilders.queryString("color:red")).endObject()) + .get(); fail(); } catch (PercolatorException e) { diff --git a/src/test/java/org/elasticsearch/search/aggregations/bucket/ParentIdAggTests.java b/src/test/java/org/elasticsearch/search/aggregations/bucket/ParentIdAggTests.java index c048c912a6186..e91d61e6cf809 100644 --- a/src/test/java/org/elasticsearch/search/aggregations/bucket/ParentIdAggTests.java +++ b/src/test/java/org/elasticsearch/search/aggregations/bucket/ParentIdAggTests.java @@ -43,7 +43,6 @@ public void testParentIdAggregation() throws IOException { .startObject("childtype") .startObject("_parent") .field("type", "parenttype") - .field("store", true) .endObject() .endObject(); assertAcked(prepareCreate("testidx").addMapping("childtype", mapping)); diff --git a/src/test/java/org/elasticsearch/search/fields/SearchFieldsTests.java b/src/test/java/org/elasticsearch/search/fields/SearchFieldsTests.java index 509088c3d0908..f25a4d02f69bb 100644 --- a/src/test/java/org/elasticsearch/search/fields/SearchFieldsTests.java +++ b/src/test/java/org/elasticsearch/search/fields/SearchFieldsTests.java @@ -428,13 +428,13 @@ public void testGetFields_complexField() throws Exception { client().admin().indices().prepareCreate("my-index") .setSettings(ImmutableSettings.settingsBuilder().put("index.refresh_interval", -1)) .addMapping("my-type2", jsonBuilder().startObject().startObject("my-type2").startObject("properties") - .startObject("field1").field("type", "object") - .startObject("field2").field("type", "object") - .startObject("field3").field("type", "object") + .startObject("field1").field("type", "object").startObject("properties") + .startObject("field2").field("type", "object").startObject("properties") + .startObject("field3").field("type", "object").startObject("properties") .startObject("field4").field("type", "string").field("store", "yes") - .endObject() - .endObject() - .endObject() + .endObject().endObject() + .endObject().endObject() + .endObject().endObject() .endObject().endObject().endObject()) .get(); diff --git a/src/test/java/org/elasticsearch/search/geo/GeoFilterTests.java b/src/test/java/org/elasticsearch/search/geo/GeoFilterTests.java index b1abb267fe04e..4277593e22e6e 100644 --- a/src/test/java/org/elasticsearch/search/geo/GeoFilterTests.java +++ b/src/test/java/org/elasticsearch/search/geo/GeoFilterTests.java @@ -224,7 +224,6 @@ public void testShapeRelations() throws Exception { .startObject("area") .field("type", "geo_shape") .field("tree", "geohash") - .field("store", true) .endObject() .endObject() .endObject() @@ -405,8 +404,6 @@ public void bulktest() throws Exception { .endObject() .startObject("location") .field("type", "geo_shape") - .field("lat_lon", true) - .field("store", true) .endObject() .endObject() .endObject() @@ -477,7 +474,7 @@ public void testGeohashCellFilter() throws IOException { ensureYellow(); - client().admin().indices().prepareCreate("locations").addMapping("location", "pin", "type=geo_point,geohash_prefix=true,latlon=false").execute().actionGet(); + client().admin().indices().prepareCreate("locations").addMapping("location", "pin", "type=geo_point,geohash_prefix=true,lat_lon=false").execute().actionGet(); // Index a pin client().prepareIndex("locations", "location", "1").setCreate(true).setSource("pin", geohash).execute().actionGet(); diff --git a/src/test/java/org/elasticsearch/search/highlight/HighlighterSearchTests.java b/src/test/java/org/elasticsearch/search/highlight/HighlighterSearchTests.java index 8bf1d7b73a40b..3bf59ec3d108b 100644 --- a/src/test/java/org/elasticsearch/search/highlight/HighlighterSearchTests.java +++ b/src/test/java/org/elasticsearch/search/highlight/HighlighterSearchTests.java @@ -1477,7 +1477,7 @@ public void testPlainHighlighterMultipleFields() { @Test public void testFastVectorHighlighterMultipleFields() { assertAcked(prepareCreate("test") - .addMapping("type1", "field1", "type=string,term_vectors=with_positions_offsets", "field2", "type=string,term_vectors=with_positions_offsets")); + .addMapping("type1", "field1", "type=string,term_vector=with_positions_offsets", "field2", "type=string,term_vector=with_positions_offsets")); ensureGreen(); index("test", "type1", "1", "field1", "The quick brown fox", "field2", "The slow brown fox"); diff --git a/src/test/java/org/elasticsearch/search/query/MultiMatchQueryTests.java b/src/test/java/org/elasticsearch/search/query/MultiMatchQueryTests.java index 69ecc98646f80..59359619cdb61 100644 --- a/src/test/java/org/elasticsearch/search/query/MultiMatchQueryTests.java +++ b/src/test/java/org/elasticsearch/search/query/MultiMatchQueryTests.java @@ -133,19 +133,16 @@ private XContentBuilder createMapping() throws IOException { .startObject("category") .field("type", "string") .field("analyzer", "category") - .field("index_option", "docs") .endObject() .startObject("first_name") .field("type", "string") .field("omit_norms", "true") .field("copy_to", "first_name_phrase") - .field("index_option", "docs") .endObject() .startObject("last_name") .field("type", "string") .field("omit_norms", "true") .field("copy_to", "last_name_phrase") - .field("index_option", "docs") .endObject() .endObject() .endObject().endObject(); diff --git a/src/test/java/org/elasticsearch/search/suggest/context/GeoLocationContextMappingTest.java b/src/test/java/org/elasticsearch/search/suggest/context/GeoLocationContextMappingTest.java index 23d0459247f06..1f6bd5eea7c11 100644 --- a/src/test/java/org/elasticsearch/search/suggest/context/GeoLocationContextMappingTest.java +++ b/src/test/java/org/elasticsearch/search/suggest/context/GeoLocationContextMappingTest.java @@ -135,8 +135,9 @@ public void testHashcode() throws Exception { pointAsMap.put("lon", 0d); config.put("default", pointAsMap); } + HashMap config2 = new HashMap<>(config); GeolocationContextMapping mapping = GeolocationContextMapping.load("foo", config); - GeolocationContextMapping mapping2 = GeolocationContextMapping.load("foo", config); + GeolocationContextMapping mapping2 = GeolocationContextMapping.load("foo", config2); assertEquals(mapping, mapping2); assertEquals(mapping.hashCode(), mapping2.hashCode());