From bc47c577d2d4192a2dd248e774d9e5028125a0bf Mon Sep 17 00:00:00 2001 From: Adrien Grand Date: Wed, 27 Jan 2016 15:02:41 +0100 Subject: [PATCH] Add a new `keyword` field. The `keyword` field is intended to replace `not_analyzed` string fields. It is indexed and has doc values by default, and doesn't support enabling term vectors. Although it doesn't support setting an analyzer for now, there are plans for it to support basic normalization in the future such as case folding. --- .../fielddata/IndexFieldDataService.java | 6 + .../index/mapper/core/KeywordFieldMapper.java | 274 ++++++++++++++++++ .../mapper/internal/ParentFieldMapper.java | 12 +- .../percolator/PercolatorFieldMapper.java | 17 +- .../index/termvectors/TermVectorsService.java | 4 +- .../elasticsearch/indices/IndicesModule.java | 2 + .../indices/stats/IndicesStatsTests.java | 10 +- .../action/termvectors/GetTermVectorsIT.java | 2 +- .../cluster/SimpleClusterStateIT.java | 2 +- .../org/elasticsearch/cluster/ack/AckIT.java | 4 +- .../gateway/RecoveryFromGatewayIT.java | 4 +- .../index/IndexWithShadowReplicasIT.java | 4 +- .../index/mapper/DynamicMappingTests.java | 3 +- .../copyto/CopyToMapperIntegrationIT.java | 2 +- .../mapper/core/KeywordFieldMapperTests.java | 203 +++++++++++++ .../mapper/core/KeywordFieldTypeTests.java | 29 ++ .../ExternalValuesMapperIntegrationIT.java | 3 +- .../SimpleExternalMappingTests.java | 5 +- .../multifield/MultiFieldsIntegrationIT.java | 33 +-- .../object/SimpleObjectMappingTests.java | 3 +- .../mapping/SimpleGetFieldMappingsIT.java | 5 +- .../mapping/UpdateMappingIntegrationIT.java | 4 +- .../RandomExceptionCircuitBreakerIT.java | 3 +- .../indices/state/OpenCloseIndexIT.java | 3 +- .../template/IndexTemplateBlocksIT.java | 2 +- .../template/SimpleIndexTemplateIT.java | 14 +- .../percolator/PercolatorIT.java | 2 +- .../aggregations/bucket/ChildrenIT.java | 4 +- .../aggregations/bucket/GeoDistanceIT.java | 4 +- .../aggregations/bucket/GeoHashGridIT.java | 4 +- .../search/aggregations/bucket/NestedIT.java | 6 +- .../search/aggregations/bucket/SamplerIT.java | 6 +- .../aggregations/bucket/ShardSizeTermsIT.java | 10 +- .../bucket/SignificantTermsIT.java | 2 +- .../SignificantTermsSignificanceScoreIT.java | 2 +- .../metrics/AbstractGeoTestCase.java | 6 +- .../aggregations/metrics/TopHitsIT.java | 3 +- .../basic/SearchWithRandomExceptionsIT.java | 3 +- .../basic/SearchWithRandomIOExceptionsIT.java | 3 +- .../search/query/SearchQueryIT.java | 3 +- .../search/searchafter/SearchAfterIT.java | 2 +- .../search/sort/FieldSortIT.java | 21 +- .../messy/tests/EquivalenceTests.java | 8 +- .../messy/tests/SearchFieldsTests.java | 4 +- .../messy/tests/SimpleSortTests.java | 4 +- .../test/indices.put_mapping/10_basic.yaml | 5 +- 46 files changed, 624 insertions(+), 131 deletions(-) create mode 100644 core/src/main/java/org/elasticsearch/index/mapper/core/KeywordFieldMapper.java create mode 100644 core/src/test/java/org/elasticsearch/index/mapper/core/KeywordFieldMapperTests.java create mode 100644 core/src/test/java/org/elasticsearch/index/mapper/core/KeywordFieldTypeTests.java diff --git a/core/src/main/java/org/elasticsearch/index/fielddata/IndexFieldDataService.java b/core/src/main/java/org/elasticsearch/index/fielddata/IndexFieldDataService.java index f02f924bc39..78bdcb0f7f3 100644 --- a/core/src/main/java/org/elasticsearch/index/fielddata/IndexFieldDataService.java +++ b/core/src/main/java/org/elasticsearch/index/fielddata/IndexFieldDataService.java @@ -36,6 +36,7 @@ import org.elasticsearch.index.fielddata.plain.ParentChildIndexFieldData; import org.elasticsearch.index.mapper.MappedFieldType; import org.elasticsearch.index.mapper.MapperService; import org.elasticsearch.index.mapper.core.BooleanFieldMapper; +import org.elasticsearch.index.mapper.core.KeywordFieldMapper; import org.elasticsearch.index.mapper.internal.IndexFieldMapper; import org.elasticsearch.index.mapper.internal.ParentFieldMapper; import org.elasticsearch.index.shard.ShardId; @@ -94,6 +95,7 @@ public class IndexFieldDataService extends AbstractIndexComponent implements Clo static { Map buildersByTypeBuilder = new HashMap<>(); buildersByTypeBuilder.put("string", new PagedBytesIndexFieldData.Builder()); + buildersByTypeBuilder.put(KeywordFieldMapper.CONTENT_TYPE, MISSING_DOC_VALUES_BUILDER); buildersByTypeBuilder.put("float", MISSING_DOC_VALUES_BUILDER); buildersByTypeBuilder.put("double", MISSING_DOC_VALUES_BUILDER); buildersByTypeBuilder.put("byte", MISSING_DOC_VALUES_BUILDER); @@ -110,6 +112,7 @@ public class IndexFieldDataService extends AbstractIndexComponent implements Clo docValuesBuildersByType = MapBuilder.newMapBuilder() .put("string", new DocValuesIndexFieldData.Builder()) + .put(KeywordFieldMapper.CONTENT_TYPE, new DocValuesIndexFieldData.Builder()) .put("float", new DocValuesIndexFieldData.Builder().numericType(IndexNumericFieldData.NumericType.FLOAT)) .put("double", new DocValuesIndexFieldData.Builder().numericType(IndexNumericFieldData.NumericType.DOUBLE)) .put("byte", new DocValuesIndexFieldData.Builder().numericType(IndexNumericFieldData.NumericType.BYTE)) @@ -126,6 +129,9 @@ public class IndexFieldDataService extends AbstractIndexComponent implements Clo .put(Tuple.tuple("string", DOC_VALUES_FORMAT), new DocValuesIndexFieldData.Builder()) .put(Tuple.tuple("string", DISABLED_FORMAT), DISABLED_BUILDER) + .put(Tuple.tuple(KeywordFieldMapper.CONTENT_TYPE, DOC_VALUES_FORMAT), new DocValuesIndexFieldData.Builder()) + .put(Tuple.tuple(KeywordFieldMapper.CONTENT_TYPE, DISABLED_FORMAT), DISABLED_BUILDER) + .put(Tuple.tuple("float", DOC_VALUES_FORMAT), new DocValuesIndexFieldData.Builder().numericType(IndexNumericFieldData.NumericType.FLOAT)) .put(Tuple.tuple("float", DISABLED_FORMAT), DISABLED_BUILDER) diff --git a/core/src/main/java/org/elasticsearch/index/mapper/core/KeywordFieldMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/core/KeywordFieldMapper.java new file mode 100644 index 00000000000..35f1ee7ad58 --- /dev/null +++ b/core/src/main/java/org/elasticsearch/index/mapper/core/KeywordFieldMapper.java @@ -0,0 +1,274 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.elasticsearch.index.mapper.core; + +import org.apache.lucene.document.Field; +import org.apache.lucene.document.SortedSetDocValuesField; +import org.apache.lucene.index.IndexOptions; +import org.apache.lucene.search.Query; +import org.apache.lucene.util.BytesRef; +import org.elasticsearch.common.Strings; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.xcontent.XContentBuilder; +import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.common.xcontent.support.XContentMapValues; +import org.elasticsearch.index.mapper.FieldMapper; +import org.elasticsearch.index.mapper.MappedFieldType; +import org.elasticsearch.index.mapper.Mapper; +import org.elasticsearch.index.mapper.MapperParsingException; +import org.elasticsearch.index.mapper.ParseContext; +import org.elasticsearch.index.mapper.internal.AllFieldMapper; + +import java.io.IOException; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import static org.elasticsearch.index.mapper.core.TypeParsers.parseField; +import static org.elasticsearch.index.mapper.core.TypeParsers.parseMultiField; + +/** + * A field mapper for keywords. This mapper accepts strings and indexes them as-is. + */ +public final class KeywordFieldMapper extends FieldMapper implements AllFieldMapper.IncludeInAll { + + public static final String CONTENT_TYPE = "keyword"; + + public static class Defaults { + public static final MappedFieldType FIELD_TYPE = new KeywordFieldType(); + + static { + FIELD_TYPE.setTokenized(false); + FIELD_TYPE.setOmitNorms(true); + FIELD_TYPE.setIndexOptions(IndexOptions.DOCS); + FIELD_TYPE.freeze(); + } + + public static final String NULL_VALUE = null; + public static final int IGNORE_ABOVE = Integer.MAX_VALUE; + } + + public static class Builder extends FieldMapper.Builder { + + protected String nullValue = Defaults.NULL_VALUE; + protected int ignoreAbove = Defaults.IGNORE_ABOVE; + + public Builder(String name) { + super(name, Defaults.FIELD_TYPE, Defaults.FIELD_TYPE); + builder = this; + } + + public Builder ignoreAbove(int ignoreAbove) { + if (ignoreAbove < 0) { + throw new IllegalArgumentException("[ignore_above] must be positive, got " + ignoreAbove); + } + this.ignoreAbove = ignoreAbove; + return this; + } + + @Override + public Builder indexOptions(IndexOptions indexOptions) { + if (fieldType.indexOptions().compareTo(IndexOptions.DOCS_AND_FREQS) > 0) { + throw new IllegalArgumentException("The [keyword] field does not support positions, got [index_options]=" + + indexOptionToString(fieldType.indexOptions())); + } + return super.indexOptions(indexOptions); + } + + @Override + public KeywordFieldMapper build(BuilderContext context) { + setupFieldType(context); + KeywordFieldMapper fieldMapper = new KeywordFieldMapper( + name, fieldType, defaultFieldType, ignoreAbove, + context.indexSettings(), multiFieldsBuilder.build(this, context), copyTo); + return fieldMapper.includeInAll(includeInAll); + } + } + + public static class TypeParser implements Mapper.TypeParser { + @Override + public Mapper.Builder parse(String name, Map node, ParserContext parserContext) throws MapperParsingException { + KeywordFieldMapper.Builder builder = new KeywordFieldMapper.Builder(name); + parseField(builder, name, node, parserContext); + 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")) { + if (propNode == null) { + throw new MapperParsingException("Property [null_value] cannot be null."); + } + builder.nullValue(propNode.toString()); + iterator.remove(); + } else if (propName.equals("ignore_above")) { + builder.ignoreAbove(XContentMapValues.nodeIntegerValue(propNode, -1)); + iterator.remove(); + } else if (parseMultiField(builder, name, parserContext, propName, propNode)) { + iterator.remove(); + } + } + return builder; + } + } + + public static final class KeywordFieldType extends MappedFieldType { + + public KeywordFieldType() {} + + protected KeywordFieldType(KeywordFieldType ref) { + super(ref); + } + + public KeywordFieldType clone() { + return new KeywordFieldType(this); + } + + @Override + public String typeName() { + return CONTENT_TYPE; + } + + @Override + public String value(Object value) { + if (value == null) { + return null; + } + return value.toString(); + } + + @Override + public Query nullValueQuery() { + if (nullValue() == null) { + return null; + } + return termQuery(nullValue(), null); + } + } + + private Boolean includeInAll; + private int ignoreAbove; + + protected KeywordFieldMapper(String simpleName, MappedFieldType fieldType, MappedFieldType defaultFieldType, + int ignoreAbove, Settings indexSettings, MultiFields multiFields, CopyTo copyTo) { + super(simpleName, fieldType, defaultFieldType, indexSettings, multiFields, copyTo); + assert fieldType.indexOptions().compareTo(IndexOptions.DOCS_AND_FREQS) <= 0; + this.ignoreAbove = ignoreAbove; + } + + @Override + protected KeywordFieldMapper clone() { + return (KeywordFieldMapper) super.clone(); + } + + @Override + public KeywordFieldMapper includeInAll(Boolean includeInAll) { + if (includeInAll != null) { + KeywordFieldMapper clone = clone(); + clone.includeInAll = includeInAll; + return clone; + } else { + return this; + } + } + + @Override + public KeywordFieldMapper includeInAllIfNotSet(Boolean includeInAll) { + if (includeInAll != null && this.includeInAll == null) { + KeywordFieldMapper clone = clone(); + clone.includeInAll = includeInAll; + return clone; + } else { + return this; + } + } + + @Override + public KeywordFieldMapper unsetIncludeInAll() { + if (includeInAll != null) { + KeywordFieldMapper clone = clone(); + clone.includeInAll = null; + return clone; + } else { + return this; + } + } + + @Override + protected void parseCreateField(ParseContext context, List fields) throws IOException { + final String value; + if (context.externalValueSet()) { + value = context.externalValue().toString(); + } else { + XContentParser parser = context.parser(); + if (parser.currentToken() == XContentParser.Token.VALUE_NULL) { + value = fieldType().nullValueAsString(); + } else { + value = parser.textOrNull(); + } + } + + if (value == null || value.length() > ignoreAbove) { + return; + } + + if (context.includeInAll(includeInAll, this)) { + context.allEntries().addText(fieldType().name(), value, fieldType().boost()); + } + + if (fieldType().indexOptions() != IndexOptions.NONE || fieldType().stored()) { + Field field = new Field(fieldType().name(), value, fieldType()); + fields.add(field); + } + if (fieldType().hasDocValues()) { + fields.add(new SortedSetDocValuesField(fieldType().name(), new BytesRef(value))); + } + } + + @Override + protected String contentType() { + return CONTENT_TYPE; + } + + @Override + protected void doMerge(Mapper mergeWith, boolean updateAllTypes) { + super.doMerge(mergeWith, updateAllTypes); + this.includeInAll = ((KeywordFieldMapper) mergeWith).includeInAll; + this.ignoreAbove = ((KeywordFieldMapper) mergeWith).ignoreAbove; + } + + @Override + protected void doXContentBody(XContentBuilder builder, boolean includeDefaults, Params params) throws IOException { + super.doXContentBody(builder, includeDefaults, params); + + if (includeDefaults || fieldType().nullValue() != null) { + builder.field("null_value", fieldType().nullValue()); + } + + if (includeInAll != null) { + builder.field("include_in_all", includeInAll); + } else if (includeDefaults) { + builder.field("include_in_all", true); + } + + if (includeDefaults || ignoreAbove != Defaults.IGNORE_ABOVE) { + builder.field("ignore_above", ignoreAbove); + } + } +} diff --git a/core/src/main/java/org/elasticsearch/index/mapper/internal/ParentFieldMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/internal/ParentFieldMapper.java index e5b0d0caaf2..66e754e5fda 100644 --- a/core/src/main/java/org/elasticsearch/index/mapper/internal/ParentFieldMapper.java +++ b/core/src/main/java/org/elasticsearch/index/mapper/internal/ParentFieldMapper.java @@ -42,7 +42,7 @@ import org.elasticsearch.index.mapper.MapperParsingException; import org.elasticsearch.index.mapper.MetadataFieldMapper; import org.elasticsearch.index.mapper.ParseContext; import org.elasticsearch.index.mapper.Uid; -import org.elasticsearch.index.mapper.core.StringFieldMapper; +import org.elasticsearch.index.mapper.core.KeywordFieldMapper; import org.elasticsearch.index.query.QueryShardContext; import java.io.IOException; @@ -131,15 +131,15 @@ public class ParentFieldMapper extends MetadataFieldMapper { @Override public MetadataFieldMapper getDefault(Settings indexSettings, MappedFieldType fieldType, String typeName) { - StringFieldMapper parentJoinField = createParentJoinFieldMapper(typeName, new BuilderContext(indexSettings, new ContentPath(0))); + KeywordFieldMapper parentJoinField = createParentJoinFieldMapper(typeName, new BuilderContext(indexSettings, new ContentPath(0))); MappedFieldType childJoinFieldType = Defaults.FIELD_TYPE.clone(); childJoinFieldType.setName(joinField(null)); return new ParentFieldMapper(parentJoinField, childJoinFieldType, null, indexSettings); } } - static StringFieldMapper createParentJoinFieldMapper(String docType, BuilderContext context) { - StringFieldMapper.Builder parentJoinField = new StringFieldMapper.Builder(joinField(docType)); + static KeywordFieldMapper createParentJoinFieldMapper(String docType, BuilderContext context) { + KeywordFieldMapper.Builder parentJoinField = new KeywordFieldMapper.Builder(joinField(docType)); parentJoinField.indexOptions(IndexOptions.NONE); parentJoinField.docValues(true); parentJoinField.fieldType().setDocValuesType(DocValuesType.SORTED); @@ -205,9 +205,9 @@ public class ParentFieldMapper extends MetadataFieldMapper { private final String parentType; // has no impact of field data settings, is just here for creating a join field, // the parent field mapper in the child type pointing to this type determines the field data settings for this join field - private final StringFieldMapper parentJoinField; + private final KeywordFieldMapper parentJoinField; - private ParentFieldMapper(StringFieldMapper parentJoinField, MappedFieldType childJoinFieldType, String parentType, Settings indexSettings) { + private ParentFieldMapper(KeywordFieldMapper parentJoinField, MappedFieldType childJoinFieldType, String parentType, Settings indexSettings) { super(NAME, childJoinFieldType, Defaults.FIELD_TYPE, indexSettings); this.parentType = parentType; this.parentJoinField = parentJoinField; diff --git a/core/src/main/java/org/elasticsearch/index/percolator/PercolatorFieldMapper.java b/core/src/main/java/org/elasticsearch/index/percolator/PercolatorFieldMapper.java index 21082805f22..f44d454655e 100644 --- a/core/src/main/java/org/elasticsearch/index/percolator/PercolatorFieldMapper.java +++ b/core/src/main/java/org/elasticsearch/index/percolator/PercolatorFieldMapper.java @@ -28,7 +28,7 @@ import org.elasticsearch.index.mapper.MappedFieldType; import org.elasticsearch.index.mapper.Mapper; import org.elasticsearch.index.mapper.MapperParsingException; import org.elasticsearch.index.mapper.ParseContext; -import org.elasticsearch.index.mapper.core.StringFieldMapper; +import org.elasticsearch.index.mapper.core.KeywordFieldMapper; import org.elasticsearch.index.query.QueryShardContext; import java.io.IOException; @@ -60,17 +60,16 @@ public class PercolatorFieldMapper extends FieldMapper { @Override public PercolatorFieldMapper build(BuilderContext context) { context.path().add(name); - StringFieldMapper extractedTermsField = createStringFieldBuilder(EXTRACTED_TERMS_FIELD_NAME).build(context); - StringFieldMapper unknownQueryField = createStringFieldBuilder(UNKNOWN_QUERY_FIELD_NAME).build(context); + KeywordFieldMapper extractedTermsField = createStringFieldBuilder(EXTRACTED_TERMS_FIELD_NAME).build(context); + KeywordFieldMapper unknownQueryField = createStringFieldBuilder(UNKNOWN_QUERY_FIELD_NAME).build(context); context.path().remove(); return new PercolatorFieldMapper(name(), fieldType, defaultFieldType, context.indexSettings(), multiFieldsBuilder.build(this, context), copyTo, queryShardContext, extractedTermsField, unknownQueryField); } - static StringFieldMapper.Builder createStringFieldBuilder(String name) { - StringFieldMapper.Builder queryMetaDataFieldBuilder = new StringFieldMapper.Builder(name); + static KeywordFieldMapper.Builder createStringFieldBuilder(String name) { + KeywordFieldMapper.Builder queryMetaDataFieldBuilder = new KeywordFieldMapper.Builder(name); queryMetaDataFieldBuilder.docValues(false); queryMetaDataFieldBuilder.store(false); - queryMetaDataFieldBuilder.tokenized(false); queryMetaDataFieldBuilder.indexOptions(IndexOptions.DOCS); return queryMetaDataFieldBuilder; } @@ -110,10 +109,10 @@ public class PercolatorFieldMapper extends FieldMapper { private final boolean mapUnmappedFieldAsString; private final QueryShardContext queryShardContext; - private final StringFieldMapper queryTermsField; - private final StringFieldMapper unknownQueryField; + private final KeywordFieldMapper queryTermsField; + private final KeywordFieldMapper unknownQueryField; - public PercolatorFieldMapper(String simpleName, MappedFieldType fieldType, MappedFieldType defaultFieldType, Settings indexSettings, MultiFields multiFields, CopyTo copyTo, QueryShardContext queryShardContext, StringFieldMapper queryTermsField, StringFieldMapper unknownQueryField) { + public PercolatorFieldMapper(String simpleName, MappedFieldType fieldType, MappedFieldType defaultFieldType, Settings indexSettings, MultiFields multiFields, CopyTo copyTo, QueryShardContext queryShardContext, KeywordFieldMapper queryTermsField, KeywordFieldMapper unknownQueryField) { super(simpleName, fieldType, defaultFieldType, indexSettings, multiFields, copyTo); this.queryShardContext = queryShardContext; this.queryTermsField = queryTermsField; diff --git a/core/src/main/java/org/elasticsearch/index/termvectors/TermVectorsService.java b/core/src/main/java/org/elasticsearch/index/termvectors/TermVectorsService.java index 271d5a353bc..e3885816cd2 100644 --- a/core/src/main/java/org/elasticsearch/index/termvectors/TermVectorsService.java +++ b/core/src/main/java/org/elasticsearch/index/termvectors/TermVectorsService.java @@ -44,6 +44,7 @@ import org.elasticsearch.index.mapper.MapperService; import org.elasticsearch.index.mapper.ParseContext; import org.elasticsearch.index.mapper.ParsedDocument; import org.elasticsearch.index.mapper.Uid; +import org.elasticsearch.index.mapper.core.KeywordFieldMapper; import org.elasticsearch.index.mapper.core.StringFieldMapper; import org.elasticsearch.index.mapper.internal.UidFieldMapper; import org.elasticsearch.index.shard.IndexShard; @@ -158,7 +159,8 @@ public class TermVectorsService { private static boolean isValidField(MappedFieldType fieldType) { // must be a string - if (!(fieldType instanceof StringFieldMapper.StringFieldType)) { + if (fieldType instanceof StringFieldMapper.StringFieldType == false + && fieldType instanceof KeywordFieldMapper.KeywordFieldType == false) { return false; } // and must be indexed diff --git a/core/src/main/java/org/elasticsearch/indices/IndicesModule.java b/core/src/main/java/org/elasticsearch/indices/IndicesModule.java index b94ef19ec23..eab8faab8eb 100644 --- a/core/src/main/java/org/elasticsearch/indices/IndicesModule.java +++ b/core/src/main/java/org/elasticsearch/indices/IndicesModule.java @@ -34,6 +34,7 @@ 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.KeywordFieldMapper; import org.elasticsearch.index.mapper.core.LongFieldMapper; import org.elasticsearch.index.mapper.core.ShortFieldMapper; import org.elasticsearch.index.mapper.core.StringFieldMapper; @@ -96,6 +97,7 @@ public class IndicesModule extends AbstractModule { registerMapper(DateFieldMapper.CONTENT_TYPE, new DateFieldMapper.TypeParser()); registerMapper(IpFieldMapper.CONTENT_TYPE, new IpFieldMapper.TypeParser()); registerMapper(StringFieldMapper.CONTENT_TYPE, new StringFieldMapper.TypeParser()); + registerMapper(KeywordFieldMapper.CONTENT_TYPE, new KeywordFieldMapper.TypeParser()); registerMapper(TokenCountFieldMapper.CONTENT_TYPE, new TokenCountFieldMapper.TypeParser()); registerMapper(ObjectMapper.CONTENT_TYPE, new ObjectMapper.TypeParser()); registerMapper(ObjectMapper.NESTED_CONTENT_TYPE, new ObjectMapper.TypeParser()); diff --git a/core/src/test/java/org/elasticsearch/action/admin/indices/stats/IndicesStatsTests.java b/core/src/test/java/org/elasticsearch/action/admin/indices/stats/IndicesStatsTests.java index 1f18da58204..13e973504a3 100644 --- a/core/src/test/java/org/elasticsearch/action/admin/indices/stats/IndicesStatsTests.java +++ b/core/src/test/java/org/elasticsearch/action/admin/indices/stats/IndicesStatsTests.java @@ -50,10 +50,12 @@ public class IndicesStatsTests extends ESSingleNodeTestCase { .startObject("doc") .startObject("properties") .startObject("foo") - .field("type", "string") - .field("index", "not_analyzed") + .field("type", "keyword") .field("doc_values", true) .field("store", true) + .endObject() + .startObject("bar") + .field("type", "string") .field("term_vector", "with_positions_offsets_payloads") .endObject() .endObject() @@ -61,7 +63,7 @@ public class IndicesStatsTests extends ESSingleNodeTestCase { .endObject(); assertAcked(client().admin().indices().prepareCreate("test").addMapping("doc", mapping)); ensureGreen("test"); - client().prepareIndex("test", "doc", "1").setSource("foo", "bar").get(); + client().prepareIndex("test", "doc", "1").setSource("foo", "bar", "bar", "baz").get(); client().admin().indices().prepareRefresh("test").get(); IndicesStatsResponse rsp = client().admin().indices().prepareStats("test").get(); @@ -73,7 +75,7 @@ public class IndicesStatsTests extends ESSingleNodeTestCase { assertThat(stats.getDocValuesMemoryInBytes(), greaterThan(0L)); // now check multiple segments stats are merged together - client().prepareIndex("test", "doc", "2").setSource("foo", "bar").get(); + client().prepareIndex("test", "doc", "2").setSource("foo", "bar", "bar", "baz").get(); client().admin().indices().prepareRefresh("test").get(); rsp = client().admin().indices().prepareStats("test").get(); diff --git a/core/src/test/java/org/elasticsearch/action/termvectors/GetTermVectorsIT.java b/core/src/test/java/org/elasticsearch/action/termvectors/GetTermVectorsIT.java index b788b9ba230..d4f61393010 100644 --- a/core/src/test/java/org/elasticsearch/action/termvectors/GetTermVectorsIT.java +++ b/core/src/test/java/org/elasticsearch/action/termvectors/GetTermVectorsIT.java @@ -153,7 +153,7 @@ public class GetTermVectorsIT extends AbstractTermVectorsTestCase { "field1", "type=string,index=no", // no tvs "field2", "type=string,index=no,store=true", // no tvs "field3", "type=string,index=no,term_vector=yes", // no tvs - "field4", "type=string,index=not_analyzed", // yes tvs + "field4", "type=keyword", // yes tvs "field5", "type=string,index=analyzed")); // yes tvs ensureYellow(); diff --git a/core/src/test/java/org/elasticsearch/cluster/SimpleClusterStateIT.java b/core/src/test/java/org/elasticsearch/cluster/SimpleClusterStateIT.java index 11d176b4566..550891d4906 100644 --- a/core/src/test/java/org/elasticsearch/cluster/SimpleClusterStateIT.java +++ b/core/src/test/java/org/elasticsearch/cluster/SimpleClusterStateIT.java @@ -91,7 +91,7 @@ public class SimpleClusterStateIT extends ESIntegTestCase { .setOrder(0) .addMapping("type1", XContentFactory.jsonBuilder().startObject().startObject("type1").startObject("properties") .startObject("field1").field("type", "string").field("store", true).endObject() - .startObject("field2").field("type", "string").field("store", true).field("index", "not_analyzed").endObject() + .startObject("field2").field("type", "keyword").field("store", true).endObject() .endObject().endObject().endObject()) .get(); diff --git a/core/src/test/java/org/elasticsearch/cluster/ack/AckIT.java b/core/src/test/java/org/elasticsearch/cluster/ack/AckIT.java index 2ec3b11a164..eb58e597c14 100644 --- a/core/src/test/java/org/elasticsearch/cluster/ack/AckIT.java +++ b/core/src/test/java/org/elasticsearch/cluster/ack/AckIT.java @@ -270,7 +270,7 @@ public class AckIT extends ESIntegTestCase { createIndex("test"); ensureGreen(); - assertAcked(client().admin().indices().preparePutMapping("test").setType("test").setSource("field", "type=string,index=not_analyzed")); + assertAcked(client().admin().indices().preparePutMapping("test").setType("test").setSource("field", "type=keyword")); for (Client client : clients()) { assertThat(getLocalClusterState(client).metaData().indices().get("test").mapping("test"), notNullValue()); @@ -281,7 +281,7 @@ public class AckIT extends ESIntegTestCase { createIndex("test"); ensureGreen(); - PutMappingResponse putMappingResponse = client().admin().indices().preparePutMapping("test").setType("test").setSource("field", "type=string,index=not_analyzed").setTimeout("0s").get(); + PutMappingResponse putMappingResponse = client().admin().indices().preparePutMapping("test").setType("test").setSource("field", "type=keyword").setTimeout("0s").get(); assertThat(putMappingResponse.isAcknowledged(), equalTo(false)); } diff --git a/core/src/test/java/org/elasticsearch/gateway/RecoveryFromGatewayIT.java b/core/src/test/java/org/elasticsearch/gateway/RecoveryFromGatewayIT.java index dd398bd48cd..fc8452ba81d 100644 --- a/core/src/test/java/org/elasticsearch/gateway/RecoveryFromGatewayIT.java +++ b/core/src/test/java/org/elasticsearch/gateway/RecoveryFromGatewayIT.java @@ -301,8 +301,8 @@ public class RecoveryFromGatewayIT extends ESIntegTestCase { .setTemplate("te*") .setOrder(0) .addMapping("type1", XContentFactory.jsonBuilder().startObject().startObject("type1").startObject("properties") - .startObject("field1").field("type", "string").field("store", "yes").endObject() - .startObject("field2").field("type", "string").field("store", "yes").field("index", "not_analyzed").endObject() + .startObject("field1").field("type", "string").field("store", true).endObject() + .startObject("field2").field("type", "keyword").field("store", true).endObject() .endObject().endObject().endObject()) .execute().actionGet(); client.admin().indices().prepareAliases().addAlias("test", "test_alias", QueryBuilders.termQuery("field", "value")).execute().actionGet(); diff --git a/core/src/test/java/org/elasticsearch/index/IndexWithShadowReplicasIT.java b/core/src/test/java/org/elasticsearch/index/IndexWithShadowReplicasIT.java index 4ef513a9be3..d04f772ddba 100644 --- a/core/src/test/java/org/elasticsearch/index/IndexWithShadowReplicasIT.java +++ b/core/src/test/java/org/elasticsearch/index/IndexWithShadowReplicasIT.java @@ -643,7 +643,7 @@ public class IndexWithShadowReplicasIT extends ESIntegTestCase { .put(IndexMetaData.SETTING_SHARED_FILESYSTEM, true) .build(); - prepareCreate(IDX).setSettings(idxSettings).addMapping("doc", "foo", "type=string,index=not_analyzed").get(); + prepareCreate(IDX).setSettings(idxSettings).addMapping("doc", "foo", "type=keyword").get(); ensureGreen(IDX); client().prepareIndex(IDX, "doc", "1").setSource("foo", "foo").get(); @@ -725,7 +725,7 @@ public class IndexWithShadowReplicasIT extends ESIntegTestCase { .build(); // only one node, so all primaries will end up on node1 - prepareCreate(IDX).setSettings(idxSettings).addMapping("doc", "foo", "type=string,index=not_analyzed").get(); + prepareCreate(IDX).setSettings(idxSettings).addMapping("doc", "foo", "type=keyword").get(); ensureGreen(IDX); // Index some documents diff --git a/core/src/test/java/org/elasticsearch/index/mapper/DynamicMappingTests.java b/core/src/test/java/org/elasticsearch/index/mapper/DynamicMappingTests.java index 6de49877ce1..1a8ffd9e6f4 100644 --- a/core/src/test/java/org/elasticsearch/index/mapper/DynamicMappingTests.java +++ b/core/src/test/java/org/elasticsearch/index/mapper/DynamicMappingTests.java @@ -473,8 +473,7 @@ public class DynamicMappingTests extends ESSingleNodeTestCase { .field("type", "string") .startObject("fields") .startObject("raw") - .field("type", "string") - .field("index", "not_analyzed") + .field("type", "keyword") .endObject() .endObject() .endObject() diff --git a/core/src/test/java/org/elasticsearch/index/mapper/copyto/CopyToMapperIntegrationIT.java b/core/src/test/java/org/elasticsearch/index/mapper/copyto/CopyToMapperIntegrationIT.java index 4a010747624..8f1e61d8d5b 100644 --- a/core/src/test/java/org/elasticsearch/index/mapper/copyto/CopyToMapperIntegrationIT.java +++ b/core/src/test/java/org/elasticsearch/index/mapper/copyto/CopyToMapperIntegrationIT.java @@ -96,7 +96,7 @@ public class CopyToMapperIntegrationIT extends ESIntegTestCase { .startObject().startObject("template_raw") .field("match", "*_raw") .field("match_mapping_type", "string") - .startObject("mapping").field("type", "string").field("index", "not_analyzed").endObject() + .startObject("mapping").field("type", "keyword").endObject() .endObject().endObject() .startObject().startObject("template_all") diff --git a/core/src/test/java/org/elasticsearch/index/mapper/core/KeywordFieldMapperTests.java b/core/src/test/java/org/elasticsearch/index/mapper/core/KeywordFieldMapperTests.java new file mode 100644 index 00000000000..bdb3f9762ef --- /dev/null +++ b/core/src/test/java/org/elasticsearch/index/mapper/core/KeywordFieldMapperTests.java @@ -0,0 +1,203 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.elasticsearch.index.mapper.core; + +import org.apache.lucene.index.DocValuesType; +import org.apache.lucene.index.IndexOptions; +import org.apache.lucene.index.IndexableField; +import org.apache.lucene.index.IndexableFieldType; +import org.apache.lucene.util.BytesRef; +import org.elasticsearch.common.compress.CompressedXContent; +import org.elasticsearch.common.xcontent.XContentFactory; +import org.elasticsearch.index.IndexService; +import org.elasticsearch.index.mapper.DocumentMapper; +import org.elasticsearch.index.mapper.DocumentMapperParser; +import org.elasticsearch.index.mapper.ParsedDocument; +import org.elasticsearch.test.ESSingleNodeTestCase; +import org.junit.Before; + +import java.io.IOException; + +import static org.hamcrest.Matchers.equalTo; + +public class KeywordFieldMapperTests extends ESSingleNodeTestCase { + + IndexService indexService; + DocumentMapperParser parser; + + @Before + public void before() { + indexService = createIndex("test"); + parser = indexService.mapperService().documentMapperParser(); + } + + public void testDefaults() throws Exception { + String mapping = XContentFactory.jsonBuilder().startObject().startObject("type") + .startObject("properties").startObject("field").field("type", "keyword").endObject().endObject() + .endObject().endObject().string(); + + DocumentMapper mapper = parser.parse("type", new CompressedXContent(mapping)); + + assertEquals(mapping, mapper.mappingSource().toString()); + + ParsedDocument doc = mapper.parse("test", "type", "1", XContentFactory.jsonBuilder() + .startObject() + .field("field", "1234") + .endObject() + .bytes()); + + IndexableField[] fields = doc.rootDoc().getFields("field"); + assertEquals(2, fields.length); + + assertEquals("1234", fields[0].stringValue()); + IndexableFieldType fieldType = fields[0].fieldType(); + assertThat(fieldType.omitNorms(), equalTo(true)); + assertFalse(fieldType.tokenized()); + assertFalse(fieldType.stored()); + assertThat(fieldType.indexOptions(), equalTo(IndexOptions.DOCS)); + assertThat(fieldType.storeTermVectors(), equalTo(false)); + assertThat(fieldType.storeTermVectorOffsets(), equalTo(false)); + assertThat(fieldType.storeTermVectorPositions(), equalTo(false)); + assertThat(fieldType.storeTermVectorPayloads(), equalTo(false)); + assertEquals(DocValuesType.NONE, fieldType.docValuesType()); + + assertEquals(new BytesRef("1234"), fields[1].binaryValue()); + fieldType = fields[1].fieldType(); + assertThat(fieldType.indexOptions(), equalTo(IndexOptions.NONE)); + assertEquals(DocValuesType.SORTED_SET, fieldType.docValuesType()); + } + + public void testIgnoreAbove() throws IOException { + String mapping = XContentFactory.jsonBuilder().startObject().startObject("type") + .startObject("properties").startObject("field").field("type", "keyword").field("ignore_above", 5).endObject().endObject() + .endObject().endObject().string(); + + DocumentMapper mapper = parser.parse("type", new CompressedXContent(mapping)); + + assertEquals(mapping, mapper.mappingSource().toString()); + + ParsedDocument doc = mapper.parse("test", "type", "1", XContentFactory.jsonBuilder() + .startObject() + .field("field", "elk") + .endObject() + .bytes()); + + IndexableField[] fields = doc.rootDoc().getFields("field"); + assertEquals(2, fields.length); + + doc = mapper.parse("test", "type", "1", XContentFactory.jsonBuilder() + .startObject() + .field("field", "elasticsearch") + .endObject() + .bytes()); + + fields = doc.rootDoc().getFields("field"); + assertEquals(0, fields.length); + } + + public void testNullValue() throws IOException { + String mapping = XContentFactory.jsonBuilder().startObject().startObject("type") + .startObject("properties").startObject("field").field("type", "keyword").field("null_value", "uri").endObject().endObject() + .endObject().endObject().string(); + + DocumentMapper mapper = parser.parse("type", new CompressedXContent(mapping)); + + assertEquals(mapping, mapper.mappingSource().toString()); + + ParsedDocument doc = mapper.parse("test", "type", "1", XContentFactory.jsonBuilder() + .startObject() + .endObject() + .bytes()); + + IndexableField[] fields = doc.rootDoc().getFields("field"); + assertEquals(0, fields.length); + + doc = mapper.parse("test", "type", "1", XContentFactory.jsonBuilder() + .startObject() + .nullField("field") + .endObject() + .bytes()); + + fields = doc.rootDoc().getFields("field"); + assertEquals(2, fields.length); + assertEquals("uri", fields[0].stringValue()); + } + + public void testEnableStore() throws IOException { + String mapping = XContentFactory.jsonBuilder().startObject().startObject("type") + .startObject("properties").startObject("field").field("type", "keyword").field("store", true).endObject().endObject() + .endObject().endObject().string(); + + DocumentMapper mapper = parser.parse("type", new CompressedXContent(mapping)); + + assertEquals(mapping, mapper.mappingSource().toString()); + + ParsedDocument doc = mapper.parse("test", "type", "1", XContentFactory.jsonBuilder() + .startObject() + .field("field", "1234") + .endObject() + .bytes()); + + IndexableField[] fields = doc.rootDoc().getFields("field"); + assertEquals(2, fields.length); + assertTrue(fields[0].fieldType().stored()); + } + + public void testDisableIndex() throws IOException { + String mapping = XContentFactory.jsonBuilder().startObject().startObject("type") + .startObject("properties").startObject("field").field("type", "keyword").field("index", false).endObject().endObject() + .endObject().endObject().string(); + + DocumentMapper mapper = parser.parse("type", new CompressedXContent(mapping)); + + assertEquals(mapping, mapper.mappingSource().toString()); + + ParsedDocument doc = mapper.parse("test", "type", "1", XContentFactory.jsonBuilder() + .startObject() + .field("field", "1234") + .endObject() + .bytes()); + + IndexableField[] fields = doc.rootDoc().getFields("field"); + assertEquals(1, fields.length); + assertEquals(IndexOptions.NONE, fields[0].fieldType().indexOptions()); + assertEquals(DocValuesType.SORTED_SET, fields[0].fieldType().docValuesType()); + } + + public void testDisableDocValues() throws IOException { + String mapping = XContentFactory.jsonBuilder().startObject().startObject("type") + .startObject("properties").startObject("field").field("type", "keyword").field("doc_values", false).endObject().endObject() + .endObject().endObject().string(); + + DocumentMapper mapper = parser.parse("type", new CompressedXContent(mapping)); + + assertEquals(mapping, mapper.mappingSource().toString()); + + ParsedDocument doc = mapper.parse("test", "type", "1", XContentFactory.jsonBuilder() + .startObject() + .field("field", "1234") + .endObject() + .bytes()); + + IndexableField[] fields = doc.rootDoc().getFields("field"); + assertEquals(1, fields.length); + assertEquals(DocValuesType.NONE, fields[0].fieldType().docValuesType()); + } +} diff --git a/core/src/test/java/org/elasticsearch/index/mapper/core/KeywordFieldTypeTests.java b/core/src/test/java/org/elasticsearch/index/mapper/core/KeywordFieldTypeTests.java new file mode 100644 index 00000000000..699717b5893 --- /dev/null +++ b/core/src/test/java/org/elasticsearch/index/mapper/core/KeywordFieldTypeTests.java @@ -0,0 +1,29 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.elasticsearch.index.mapper.core; + +import org.elasticsearch.index.mapper.FieldTypeTestCase; +import org.elasticsearch.index.mapper.MappedFieldType; + +public class KeywordFieldTypeTests extends FieldTypeTestCase { + @Override + protected MappedFieldType createDefaultFieldType() { + return new KeywordFieldMapper.KeywordFieldType(); + } +} diff --git a/core/src/test/java/org/elasticsearch/index/mapper/externalvalues/ExternalValuesMapperIntegrationIT.java b/core/src/test/java/org/elasticsearch/index/mapper/externalvalues/ExternalValuesMapperIntegrationIT.java index f581f1f6a41..d90c39381f9 100644 --- a/core/src/test/java/org/elasticsearch/index/mapper/externalvalues/ExternalValuesMapperIntegrationIT.java +++ b/core/src/test/java/org/elasticsearch/index/mapper/externalvalues/ExternalValuesMapperIntegrationIT.java @@ -92,8 +92,7 @@ public class ExternalValuesMapperIntegrationIT extends ESIntegTestCase { .field("store", true) .startObject("fields") .startObject("raw") - .field("type", "string") - .field("index", "not_analyzed") + .field("type", "keyword") .field("store", true) .endObject() .endObject() diff --git a/core/src/test/java/org/elasticsearch/index/mapper/externalvalues/SimpleExternalMappingTests.java b/core/src/test/java/org/elasticsearch/index/mapper/externalvalues/SimpleExternalMappingTests.java index bf92991e039..8b8955d19d7 100644 --- a/core/src/test/java/org/elasticsearch/index/mapper/externalvalues/SimpleExternalMappingTests.java +++ b/core/src/test/java/org/elasticsearch/index/mapper/externalvalues/SimpleExternalMappingTests.java @@ -30,6 +30,7 @@ import org.elasticsearch.index.mapper.DocumentMapper; import org.elasticsearch.index.mapper.DocumentMapperParser; import org.elasticsearch.index.mapper.Mapper; import org.elasticsearch.index.mapper.ParsedDocument; +import org.elasticsearch.index.mapper.core.KeywordFieldMapper; import org.elasticsearch.index.mapper.core.StringFieldMapper; import org.elasticsearch.indices.mapper.MapperRegistry; import org.elasticsearch.plugins.Plugin; @@ -106,6 +107,7 @@ public class SimpleExternalMappingTests extends ESSingleNodeTestCase { Map mapperParsers = new HashMap<>(); mapperParsers.put(ExternalMapperPlugin.EXTERNAL, new ExternalMapper.TypeParser(ExternalMapperPlugin.EXTERNAL, "foo")); mapperParsers.put(StringFieldMapper.CONTENT_TYPE, new StringFieldMapper.TypeParser()); + mapperParsers.put(KeywordFieldMapper.CONTENT_TYPE, new KeywordFieldMapper.TypeParser()); MapperRegistry mapperRegistry = new MapperRegistry(mapperParsers, Collections.emptyMap()); DocumentMapperParser parser = new DocumentMapperParser(indexService.getIndexSettings(), indexService.mapperService(), @@ -121,8 +123,7 @@ public class SimpleExternalMappingTests extends ESSingleNodeTestCase { .field("store", true) .startObject("fields") .startObject("raw") - .field("type", "string") - .field("index", "not_analyzed") + .field("type", "keyword") .field("store", true) .endObject() .endObject() diff --git a/core/src/test/java/org/elasticsearch/index/mapper/multifield/MultiFieldsIntegrationIT.java b/core/src/test/java/org/elasticsearch/index/mapper/multifield/MultiFieldsIntegrationIT.java index 347e4dd9201..bb24a41c445 100644 --- a/core/src/test/java/org/elasticsearch/index/mapper/multifield/MultiFieldsIntegrationIT.java +++ b/core/src/test/java/org/elasticsearch/index/mapper/multifield/MultiFieldsIntegrationIT.java @@ -57,7 +57,7 @@ public class MultiFieldsIntegrationIT extends ESIntegTestCase { Map titleFields = ((Map) XContentMapValues.extractValue("properties.title.fields", mappingSource)); assertThat(titleFields.size(), equalTo(1)); assertThat(titleFields.get("not_analyzed"), notNullValue()); - assertThat(((Map)titleFields.get("not_analyzed")).get("index").toString(), equalTo("not_analyzed")); + assertThat(((Map)titleFields.get("not_analyzed")).get("type").toString(), equalTo("keyword")); client().prepareIndex("my-index", "my-type", "1") .setSource("title", "Multi fields") @@ -86,7 +86,7 @@ public class MultiFieldsIntegrationIT extends ESIntegTestCase { titleFields = ((Map) XContentMapValues.extractValue("properties.title.fields", mappingSource)); assertThat(titleFields.size(), equalTo(2)); assertThat(titleFields.get("not_analyzed"), notNullValue()); - assertThat(((Map)titleFields.get("not_analyzed")).get("index").toString(), equalTo("not_analyzed")); + assertThat(((Map)titleFields.get("not_analyzed")).get("type").toString(), equalTo("keyword")); assertThat(titleFields.get("uncased"), notNullValue()); assertThat(((Map)titleFields.get("uncased")).get("analyzer").toString(), equalTo("whitespace")); @@ -118,9 +118,8 @@ public class MultiFieldsIntegrationIT extends ESIntegTestCase { assertThat(aField.get("fields"), notNullValue()); Map bField = ((Map) XContentMapValues.extractValue("properties.a.fields.b", mappingSource)); - assertThat(bField.size(), equalTo(2)); - assertThat(bField.get("type").toString(), equalTo("string")); - assertThat(bField.get("index").toString(), equalTo("not_analyzed")); + assertThat(bField.size(), equalTo(1)); + assertThat(bField.get("type").toString(), equalTo("keyword")); GeoPoint point = new GeoPoint(51, 19); client().prepareIndex("my-index", "my-type", "1").setSource("a", point.toString()).setRefresh(true).get(); @@ -142,8 +141,7 @@ public class MultiFieldsIntegrationIT extends ESIntegTestCase { .field("analyzer", "simple") .startObject("fields") .startObject("b") - .field("type", "string") - .field("index", "not_analyzed") + .field("type", "keyword") .endObject() .endObject() .endObject() @@ -161,9 +159,8 @@ public class MultiFieldsIntegrationIT extends ESIntegTestCase { assertThat(aField.get("fields"), notNullValue()); Map bField = ((Map) XContentMapValues.extractValue("properties.a.fields.b", mappingSource)); - assertThat(bField.size(), equalTo(2)); - assertThat(bField.get("type").toString(), equalTo("string")); - assertThat(bField.get("index").toString(), equalTo("not_analyzed")); + assertThat(bField.size(), equalTo(1)); + assertThat(bField.get("type").toString(), equalTo("keyword")); client().prepareIndex("my-index", "my-type", "1").setSource("a", "my tokens").setRefresh(true).get(); SearchResponse countResponse = client().prepareSearch("my-index").setSize(0).setQuery(matchQuery("a.b", "my tokens")).get(); @@ -186,9 +183,8 @@ public class MultiFieldsIntegrationIT extends ESIntegTestCase { assertThat(aField.get("fields"), notNullValue()); Map bField = ((Map) XContentMapValues.extractValue("properties.a.fields.b", mappingSource)); - assertThat(bField.size(), equalTo(2)); - assertThat(bField.get("type").toString(), equalTo("string")); - assertThat(bField.get("index").toString(), equalTo("not_analyzed")); + assertThat(bField.size(), equalTo(1)); + assertThat(bField.get("type").toString(), equalTo("keyword")); client().prepareIndex("my-index", "my-type", "1").setSource("a", "complete me").setRefresh(true).get(); SearchResponse countResponse = client().prepareSearch("my-index").setSize(0).setQuery(matchQuery("a.b", "complete me")).get(); @@ -211,9 +207,8 @@ public class MultiFieldsIntegrationIT extends ESIntegTestCase { assertThat(aField.get("fields"), notNullValue()); Map bField = ((Map) XContentMapValues.extractValue("properties.a.fields.b", mappingSource)); - assertThat(bField.size(), equalTo(2)); - assertThat(bField.get("type").toString(), equalTo("string")); - assertThat(bField.get("index").toString(), equalTo("not_analyzed")); + assertThat(bField.size(), equalTo(1)); + assertThat(bField.get("type").toString(), equalTo("keyword")); client().prepareIndex("my-index", "my-type", "1").setSource("a", "127.0.0.1").setRefresh(true).get(); SearchResponse countResponse = client().prepareSearch("my-index").setSize(0).setQuery(matchQuery("a.b", "127.0.0.1")).get(); @@ -227,8 +222,7 @@ public class MultiFieldsIntegrationIT extends ESIntegTestCase { .field("type", fieldType) .startObject("fields") .startObject("b") - .field("type", "string") - .field("index", "not_analyzed") + .field("type", "keyword") .endObject() .endObject() .endObject() @@ -243,8 +237,7 @@ public class MultiFieldsIntegrationIT extends ESIntegTestCase { .field("type", "string") .startObject("fields") .startObject("not_analyzed") - .field("type", "string") - .field("index", "not_analyzed") + .field("type", "keyword") .endObject() .endObject() .endObject() diff --git a/core/src/test/java/org/elasticsearch/index/mapper/object/SimpleObjectMappingTests.java b/core/src/test/java/org/elasticsearch/index/mapper/object/SimpleObjectMappingTests.java index 885e038de60..423c3e04343 100644 --- a/core/src/test/java/org/elasticsearch/index/mapper/object/SimpleObjectMappingTests.java +++ b/core/src/test/java/org/elasticsearch/index/mapper/object/SimpleObjectMappingTests.java @@ -152,8 +152,7 @@ public class SimpleObjectMappingTests extends ESSingleNodeTestCase { .field("index", "analyzed") .startObject("fields") .startObject("raw") - .field("type", "string") - .field("index","not_analyzed") + .field("type", "keyword") .endObject() .endObject() .endObject() diff --git a/core/src/test/java/org/elasticsearch/indices/mapping/SimpleGetFieldMappingsIT.java b/core/src/test/java/org/elasticsearch/indices/mapping/SimpleGetFieldMappingsIT.java index a993130a91a..070772356a6 100644 --- a/core/src/test/java/org/elasticsearch/indices/mapping/SimpleGetFieldMappingsIT.java +++ b/core/src/test/java/org/elasticsearch/indices/mapping/SimpleGetFieldMappingsIT.java @@ -60,7 +60,7 @@ public class SimpleGetFieldMappingsIT extends ESIntegTestCase { private XContentBuilder getMappingForType(String type) throws IOException { return jsonBuilder().startObject().startObject(type).startObject("properties") .startObject("field1").field("type", "string").endObject() - .startObject("obj").startObject("properties").startObject("subfield").field("type", "string").field("index", "not_analyzed").endObject().endObject().endObject() + .startObject("obj").startObject("properties").startObject("subfield").field("type", "keyword").endObject().endObject().endObject() .endObject().endObject().endObject(); } @@ -147,8 +147,7 @@ public class SimpleGetFieldMappingsIT extends ESIntegTestCase { assertThat((Map) response.fieldMappings("test", "type", "num").sourceAsMap().get("num"), hasEntry("type", (Object) "long")); assertThat((Map) response.fieldMappings("test", "type", "field1").sourceAsMap().get("field1"), hasEntry("index", (Object) "analyzed")); assertThat((Map) response.fieldMappings("test", "type", "field1").sourceAsMap().get("field1"), hasEntry("type", (Object) "string")); - assertThat((Map) response.fieldMappings("test", "type", "obj.subfield").sourceAsMap().get("subfield"), hasEntry("index", (Object) "not_analyzed")); - assertThat((Map) response.fieldMappings("test", "type", "obj.subfield").sourceAsMap().get("subfield"), hasEntry("type", (Object) "string")); + assertThat((Map) response.fieldMappings("test", "type", "obj.subfield").sourceAsMap().get("subfield"), hasEntry("type", (Object) "keyword")); } diff --git a/core/src/test/java/org/elasticsearch/indices/mapping/UpdateMappingIntegrationIT.java b/core/src/test/java/org/elasticsearch/indices/mapping/UpdateMappingIntegrationIT.java index 144587a1833..3c4dc3186bc 100644 --- a/core/src/test/java/org/elasticsearch/indices/mapping/UpdateMappingIntegrationIT.java +++ b/core/src/test/java/org/elasticsearch/indices/mapping/UpdateMappingIntegrationIT.java @@ -229,7 +229,7 @@ public class UpdateMappingIntegrationIT extends ESIntegTestCase { logger.info("Changing _default_ mappings field from analyzed to non-analyzed"); putResponse = client().admin().indices().preparePutMapping("test").setType(MapperService.DEFAULT_MAPPING).setSource( JsonXContent.contentBuilder().startObject().startObject(MapperService.DEFAULT_MAPPING) - .startObject("properties").startObject("f").field("type", "string").field("index", "not_analyzed").endObject().endObject() + .startObject("properties").startObject("f").field("type", "keyword").endObject().endObject() .endObject().endObject() ).get(); assertThat(putResponse.isAcknowledged(), equalTo(true)); @@ -238,7 +238,7 @@ public class UpdateMappingIntegrationIT extends ESIntegTestCase { getResponse = client().admin().indices().prepareGetMappings("test").addTypes(MapperService.DEFAULT_MAPPING).get(); defaultMapping = getResponse.getMappings().get("test").get(MapperService.DEFAULT_MAPPING).sourceAsMap(); Map fieldSettings = (Map) ((Map) defaultMapping.get("properties")).get("f"); - assertThat(fieldSettings, hasEntry("index", (Object) "not_analyzed")); + assertThat(fieldSettings, hasEntry("type", (Object) "keyword")); // but we still validate the _default_ type logger.info("Confirming _default_ mappings validation"); diff --git a/core/src/test/java/org/elasticsearch/indices/memory/breaker/RandomExceptionCircuitBreakerIT.java b/core/src/test/java/org/elasticsearch/indices/memory/breaker/RandomExceptionCircuitBreakerIT.java index a406106f110..35ed7a2c657 100644 --- a/core/src/test/java/org/elasticsearch/indices/memory/breaker/RandomExceptionCircuitBreakerIT.java +++ b/core/src/test/java/org/elasticsearch/indices/memory/breaker/RandomExceptionCircuitBreakerIT.java @@ -75,8 +75,7 @@ public class RandomExceptionCircuitBreakerIT extends ESIntegTestCase { .startObject("type") .startObject("properties") .startObject("test-str") - .field("type", "string") - .field("index", "not_analyzed") + .field("type", "keyword") .field("doc_values", randomBoolean()) .endObject() // test-str .startObject("test-num") diff --git a/core/src/test/java/org/elasticsearch/indices/state/OpenCloseIndexIT.java b/core/src/test/java/org/elasticsearch/indices/state/OpenCloseIndexIT.java index e17b2a5c7b4..8eef10d693b 100644 --- a/core/src/test/java/org/elasticsearch/indices/state/OpenCloseIndexIT.java +++ b/core/src/test/java/org/elasticsearch/indices/state/OpenCloseIndexIT.java @@ -332,8 +332,7 @@ public class OpenCloseIndexIT extends ESIntegTestCase { startObject("type"). startObject("properties"). startObject("test") - .field("type", "string") - .field("index", "not_analyzed") + .field("type", "keyword") .endObject(). endObject(). endObject() diff --git a/core/src/test/java/org/elasticsearch/indices/template/IndexTemplateBlocksIT.java b/core/src/test/java/org/elasticsearch/indices/template/IndexTemplateBlocksIT.java index 11e2d7d2ac4..38269ebf8f1 100644 --- a/core/src/test/java/org/elasticsearch/indices/template/IndexTemplateBlocksIT.java +++ b/core/src/test/java/org/elasticsearch/indices/template/IndexTemplateBlocksIT.java @@ -39,7 +39,7 @@ public class IndexTemplateBlocksIT extends ESIntegTestCase { .setOrder(0) .addMapping("type1", XContentFactory.jsonBuilder().startObject().startObject("type1").startObject("properties") .startObject("field1").field("type", "string").field("store", true).endObject() - .startObject("field2").field("type", "string").field("store", true).field("index", "not_analyzed").endObject() + .startObject("field2").field("type", "keyword").field("store", true).endObject() .endObject().endObject().endObject()) .execute().actionGet(); diff --git a/core/src/test/java/org/elasticsearch/indices/template/SimpleIndexTemplateIT.java b/core/src/test/java/org/elasticsearch/indices/template/SimpleIndexTemplateIT.java index fbfaa93df8c..5df1b2311ca 100644 --- a/core/src/test/java/org/elasticsearch/indices/template/SimpleIndexTemplateIT.java +++ b/core/src/test/java/org/elasticsearch/indices/template/SimpleIndexTemplateIT.java @@ -79,7 +79,7 @@ public class SimpleIndexTemplateIT extends ESIntegTestCase { .setOrder(0) .addMapping("type1", XContentFactory.jsonBuilder().startObject().startObject("type1").startObject("properties") .startObject("field1").field("type", "string").field("store", true).endObject() - .startObject("field2").field("type", "string").field("store", true).field("index", "not_analyzed").endObject() + .startObject("field2").field("type", "keyword").field("store", true).endObject() .endObject().endObject().endObject()) .get(); @@ -146,7 +146,7 @@ public class SimpleIndexTemplateIT extends ESIntegTestCase { .setOrder(0) .addMapping("type1", XContentFactory.jsonBuilder().startObject().startObject("type1").startObject("properties") .startObject("field1").field("type", "string").field("store", true).endObject() - .startObject("field2").field("type", "string").field("store", true).field("index", "not_analyzed").endObject() + .startObject("field2").field("type", "string").field("store", true).endObject() .endObject().endObject().endObject()) .execute().actionGet(); @@ -171,7 +171,7 @@ public class SimpleIndexTemplateIT extends ESIntegTestCase { .setOrder(0) .addMapping("type1", XContentFactory.jsonBuilder().startObject().startObject("type1").startObject("properties") .startObject("field1").field("type", "string").field("store", true).endObject() - .startObject("field2").field("type", "string").field("store", true).field("index", "not_analyzed").endObject() + .startObject("field2").field("type", "keyword").field("store", true).endObject() .endObject().endObject().endObject()) .execute().actionGet(); @@ -191,7 +191,7 @@ public class SimpleIndexTemplateIT extends ESIntegTestCase { .setOrder(0) .addMapping("type1", XContentFactory.jsonBuilder().startObject().startObject("type1").startObject("properties") .startObject("field1").field("type", "string").field("store", true).endObject() - .startObject("field2").field("type", "string").field("store", true).field("index", "not_analyzed").endObject() + .startObject("field2").field("type", "keyword").field("store", true).endObject() .endObject().endObject().endObject()) .execute().actionGet(); @@ -214,7 +214,7 @@ public class SimpleIndexTemplateIT extends ESIntegTestCase { .setOrder(0) .addMapping("type1", XContentFactory.jsonBuilder().startObject().startObject("type1").startObject("properties") .startObject("field1").field("type", "string").field("store", true).endObject() - .startObject("field2").field("type", "string").field("store", true).field("index", "not_analyzed").endObject() + .startObject("field2").field("type", "keyword").field("store", true).endObject() .endObject().endObject().endObject()) .execute().actionGet(); @@ -224,7 +224,7 @@ public class SimpleIndexTemplateIT extends ESIntegTestCase { .setOrder(0) .addMapping("type1", XContentFactory.jsonBuilder().startObject().startObject("type1").startObject("properties") .startObject("field1").field("type", "string").field("store", true).endObject() - .startObject("field2").field("type", "string").field("store", true).field("index", "not_analyzed").endObject() + .startObject("field2").field("type", "keyword").field("store", true).endObject() .endObject().endObject().endObject()) .execute().actionGet(); @@ -234,7 +234,7 @@ public class SimpleIndexTemplateIT extends ESIntegTestCase { .setOrder(0) .addMapping("type1", XContentFactory.jsonBuilder().startObject().startObject("type1").startObject("properties") .startObject("field1").field("type", "string").field("store", true).endObject() - .startObject("field2").field("type", "string").field("store", true).field("index", "not_analyzed").endObject() + .startObject("field2").field("type", "keyword").field("store", true).endObject() .endObject().endObject().endObject()) .execute().actionGet(); diff --git a/core/src/test/java/org/elasticsearch/percolator/PercolatorIT.java b/core/src/test/java/org/elasticsearch/percolator/PercolatorIT.java index be87cc0c9a8..6d187147f2b 100644 --- a/core/src/test/java/org/elasticsearch/percolator/PercolatorIT.java +++ b/core/src/test/java/org/elasticsearch/percolator/PercolatorIT.java @@ -861,7 +861,7 @@ public class PercolatorIT extends ESIntegTestCase { public void testPercolateWithAliasFilter() throws Exception { assertAcked(prepareCreate("my-index") - .addMapping(PercolatorService.TYPE_NAME, "a", "type=string,index=not_analyzed") + .addMapping(PercolatorService.TYPE_NAME, "a", "type=keyword") .addAlias(new Alias("a").filter(QueryBuilders.termQuery("a", "a"))) .addAlias(new Alias("b").filter(QueryBuilders.termQuery("a", "b"))) .addAlias(new Alias("c").filter(QueryBuilders.termQuery("a", "c"))) diff --git a/core/src/test/java/org/elasticsearch/search/aggregations/bucket/ChildrenIT.java b/core/src/test/java/org/elasticsearch/search/aggregations/bucket/ChildrenIT.java index 2dcb79b8d50..8981a96facf 100644 --- a/core/src/test/java/org/elasticsearch/search/aggregations/bucket/ChildrenIT.java +++ b/core/src/test/java/org/elasticsearch/search/aggregations/bucket/ChildrenIT.java @@ -402,8 +402,8 @@ public class ChildrenIT extends ESIntegTestCase { assertAcked( prepareCreate("index") - .addMapping("parentType", "name", "type=string,index=not_analyzed", "town", "type=string,index=not_analyzed") - .addMapping("childType", "_parent", "type=parentType", "name", "type=string,index=not_analyzed", "age", "type=integer") + .addMapping("parentType", "name", "type=keyword", "town", "type=keyword") + .addMapping("childType", "_parent", "type=parentType", "name", "type=keyword", "age", "type=integer") ); List requests = new ArrayList<>(); requests.add(client().prepareIndex("index", "parentType", "1").setSource("name", "Bob", "town", "Memphis")); diff --git a/core/src/test/java/org/elasticsearch/search/aggregations/bucket/GeoDistanceIT.java b/core/src/test/java/org/elasticsearch/search/aggregations/bucket/GeoDistanceIT.java index 5d52d1442f7..b611f52ac4f 100644 --- a/core/src/test/java/org/elasticsearch/search/aggregations/bucket/GeoDistanceIT.java +++ b/core/src/test/java/org/elasticsearch/search/aggregations/bucket/GeoDistanceIT.java @@ -83,11 +83,11 @@ public class GeoDistanceIT extends ESIntegTestCase { public void setupSuiteScopeCluster() throws Exception { Settings settings = Settings.settingsBuilder().put(IndexMetaData.SETTING_VERSION_CREATED, version).build(); prepareCreate("idx").setSettings(settings) - .addMapping("type", "location", "type=geo_point", "city", "type=string,index=not_analyzed") + .addMapping("type", "location", "type=geo_point", "city", "type=keyword") .execute().actionGet(); prepareCreate("idx-multi") - .addMapping("type", "location", "type=geo_point", "city", "type=string,index=not_analyzed") + .addMapping("type", "location", "type=geo_point", "city", "type=keyword") .execute().actionGet(); createIndex("idx_unmapped"); diff --git a/core/src/test/java/org/elasticsearch/search/aggregations/bucket/GeoHashGridIT.java b/core/src/test/java/org/elasticsearch/search/aggregations/bucket/GeoHashGridIT.java index 672447a6811..7f3f51031d7 100644 --- a/core/src/test/java/org/elasticsearch/search/aggregations/bucket/GeoHashGridIT.java +++ b/core/src/test/java/org/elasticsearch/search/aggregations/bucket/GeoHashGridIT.java @@ -90,7 +90,7 @@ public class GeoHashGridIT extends ESIntegTestCase { Settings settings = Settings.settingsBuilder().put(IndexMetaData.SETTING_VERSION_CREATED, version).build(); assertAcked(prepareCreate("idx").setSettings(settings) - .addMapping("type", "location", "type=geo_point", "city", "type=string,index=not_analyzed")); + .addMapping("type", "location", "type=geo_point", "city", "type=keyword")); List cities = new ArrayList<>(); Random random = getRandom(); @@ -115,7 +115,7 @@ public class GeoHashGridIT extends ESIntegTestCase { indexRandom(true, cities); assertAcked(prepareCreate("multi_valued_idx").setSettings(settings) - .addMapping("type", "location", "type=geo_point", "city", "type=string,index=not_analyzed")); + .addMapping("type", "location", "type=geo_point", "city", "type=keyword")); cities = new ArrayList<>(); multiValuedExpectedDocCountsForGeoHash = new ObjectIntHashMap<>(numDocs * 2); diff --git a/core/src/test/java/org/elasticsearch/search/aggregations/bucket/NestedIT.java b/core/src/test/java/org/elasticsearch/search/aggregations/bucket/NestedIT.java index 5317f2e15f1..af17ca8e212 100644 --- a/core/src/test/java/org/elasticsearch/search/aggregations/bucket/NestedIT.java +++ b/core/src/test/java/org/elasticsearch/search/aggregations/bucket/NestedIT.java @@ -367,12 +367,12 @@ public class NestedIT extends ESIntegTestCase { .field("type", "nested") .startObject("properties") .startObject("cid").field("type", "long").endObject() - .startObject("identifier").field("type", "string").field("index", "not_analyzed").endObject() + .startObject("identifier").field("type", "keyword").endObject() .startObject("tags") .field("type", "nested") .startObject("properties") .startObject("tid").field("type", "long").endObject() - .startObject("name").field("type", "string").field("index", "not_analyzed").endObject() + .startObject("name").field("type", "keyword").endObject() .endObject() .endObject() .endObject() @@ -386,7 +386,7 @@ public class NestedIT extends ESIntegTestCase { .startObject("properties") .startObject("end").field("type", "date").field("format", "dateOptionalTime").endObject() .startObject("start").field("type", "date").field("format", "dateOptionalTime").endObject() - .startObject("label").field("type", "string").field("index", "not_analyzed").endObject() + .startObject("label").field("type", "keyword").endObject() .endObject() .endObject() .endObject() diff --git a/core/src/test/java/org/elasticsearch/search/aggregations/bucket/SamplerIT.java b/core/src/test/java/org/elasticsearch/search/aggregations/bucket/SamplerIT.java index 623d27b2cc7..b6088c88784 100644 --- a/core/src/test/java/org/elasticsearch/search/aggregations/bucket/SamplerIT.java +++ b/core/src/test/java/org/elasticsearch/search/aggregations/bucket/SamplerIT.java @@ -61,12 +61,12 @@ public class SamplerIT extends ESIntegTestCase { @Override public void setupSuiteScopeCluster() throws Exception { assertAcked(prepareCreate("test").setSettings(SETTING_NUMBER_OF_SHARDS, NUM_SHARDS, SETTING_NUMBER_OF_REPLICAS, 0).addMapping( - "book", "author", "type=string,index=not_analyzed", "name", "type=string,index=analyzed", "genre", - "type=string,index=not_analyzed", "price", "type=float")); + "book", "author", "type=keyword", "name", "type=string,index=analyzed", "genre", + "type=keyword", "price", "type=float")); createIndex("idx_unmapped"); // idx_unmapped_author is same as main index but missing author field assertAcked(prepareCreate("idx_unmapped_author").setSettings(SETTING_NUMBER_OF_SHARDS, NUM_SHARDS, SETTING_NUMBER_OF_REPLICAS, 0) - .addMapping("book", "name", "type=string,index=analyzed", "genre", "type=string,index=not_analyzed", "price", "type=float")); + .addMapping("book", "name", "type=string,index=analyzed", "genre", "type=keyword", "price", "type=float")); ensureGreen(); String data[] = { diff --git a/core/src/test/java/org/elasticsearch/search/aggregations/bucket/ShardSizeTermsIT.java b/core/src/test/java/org/elasticsearch/search/aggregations/bucket/ShardSizeTermsIT.java index 0616fa01b17..ecc16b85f13 100644 --- a/core/src/test/java/org/elasticsearch/search/aggregations/bucket/ShardSizeTermsIT.java +++ b/core/src/test/java/org/elasticsearch/search/aggregations/bucket/ShardSizeTermsIT.java @@ -32,7 +32,7 @@ import static org.hamcrest.Matchers.equalTo; public class ShardSizeTermsIT extends ShardSizeTestCase { public void testNoShardSizeString() throws Exception { - createIdx("type=string,index=not_analyzed"); + createIdx("type=keyword"); indexData(); @@ -55,7 +55,7 @@ public class ShardSizeTermsIT extends ShardSizeTestCase { } public void testShardSizeEqualsSizeString() throws Exception { - createIdx("type=string,index=not_analyzed"); + createIdx("type=keyword"); indexData(); @@ -79,7 +79,7 @@ public class ShardSizeTermsIT extends ShardSizeTestCase { public void testWithShardSizeString() throws Exception { - createIdx("type=string,index=not_analyzed"); + createIdx("type=keyword"); indexData(); @@ -103,7 +103,7 @@ public class ShardSizeTermsIT extends ShardSizeTestCase { public void testWithShardSizeStringSingleShard() throws Exception { - createIdx("type=string,index=not_analyzed"); + createIdx("type=keyword"); indexData(); @@ -126,7 +126,7 @@ public class ShardSizeTermsIT extends ShardSizeTestCase { } public void testNoShardSizeTermOrderString() throws Exception { - createIdx("type=string,index=not_analyzed"); + createIdx("type=keyword"); indexData(); diff --git a/core/src/test/java/org/elasticsearch/search/aggregations/bucket/SignificantTermsIT.java b/core/src/test/java/org/elasticsearch/search/aggregations/bucket/SignificantTermsIT.java index 97a3cfa3ba2..450e029622f 100644 --- a/core/src/test/java/org/elasticsearch/search/aggregations/bucket/SignificantTermsIT.java +++ b/core/src/test/java/org/elasticsearch/search/aggregations/bucket/SignificantTermsIT.java @@ -75,7 +75,7 @@ public class SignificantTermsIT extends ESIntegTestCase { @Override public void setupSuiteScopeCluster() throws Exception { assertAcked(prepareCreate("test").setSettings(SETTING_NUMBER_OF_SHARDS, 5, SETTING_NUMBER_OF_REPLICAS, 0).addMapping("fact", - "_routing", "required=true", "routing_id", "type=string,index=not_analyzed", "fact_category", + "_routing", "required=true", "routing_id", "type=keyword", "fact_category", "type=integer,index=true", "description", "type=string,index=analyzed")); createIndex("idx_unmapped"); diff --git a/core/src/test/java/org/elasticsearch/search/aggregations/bucket/SignificantTermsSignificanceScoreIT.java b/core/src/test/java/org/elasticsearch/search/aggregations/bucket/SignificantTermsSignificanceScoreIT.java index 6c1e7dfcabf..6daa6f2dc28 100644 --- a/core/src/test/java/org/elasticsearch/search/aggregations/bucket/SignificantTermsSignificanceScoreIT.java +++ b/core/src/test/java/org/elasticsearch/search/aggregations/bucket/SignificantTermsSignificanceScoreIT.java @@ -282,7 +282,7 @@ public class SignificantTermsSignificanceScoreIT extends ESIntegTestCase { public void testDeletesIssue7951() throws Exception { String settings = "{\"index.number_of_shards\": 1, \"index.number_of_replicas\": 0}"; - String mappings = "{\"doc\": {\"properties\":{\"text\": {\"type\":\"string\",\"index\":\"not_analyzed\"}}}}"; + String mappings = "{\"doc\": {\"properties\":{\"text\": {\"type\":\"keyword\"}}}}"; assertAcked(prepareCreate(INDEX_NAME).setSettings(settings).addMapping("doc", mappings)); String[] cat1v1 = {"constant", "one"}; String[] cat1v2 = {"constant", "uno"}; diff --git a/core/src/test/java/org/elasticsearch/search/aggregations/metrics/AbstractGeoTestCase.java b/core/src/test/java/org/elasticsearch/search/aggregations/metrics/AbstractGeoTestCase.java index 695fb87efa9..cc0e8b2050e 100644 --- a/core/src/test/java/org/elasticsearch/search/aggregations/metrics/AbstractGeoTestCase.java +++ b/core/src/test/java/org/elasticsearch/search/aggregations/metrics/AbstractGeoTestCase.java @@ -75,7 +75,7 @@ public abstract class AbstractGeoTestCase extends ESIntegTestCase { createIndex(UNMAPPED_IDX_NAME); assertAcked(prepareCreate(IDX_NAME) .addMapping("type", SINGLE_VALUED_FIELD_NAME, "type=geo_point,geohash_prefix=true,geohash_precision=12", - MULTI_VALUED_FIELD_NAME, "type=geo_point", NUMBER_FIELD_NAME, "type=long", "tag", "type=string,index=not_analyzed")); + MULTI_VALUED_FIELD_NAME, "type=geo_point", NUMBER_FIELD_NAME, "type=long", "tag", "type=keyword")); singleTopLeft = new GeoPoint(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY); singleBottomRight = new GeoPoint(Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY); @@ -136,7 +136,7 @@ public abstract class AbstractGeoTestCase extends ESIntegTestCase { assertAcked(prepareCreate(EMPTY_IDX_NAME).addMapping("type", SINGLE_VALUED_FIELD_NAME, "type=geo_point")); assertAcked(prepareCreate(DATELINE_IDX_NAME) - .addMapping("type", SINGLE_VALUED_FIELD_NAME, "type=geo_point", MULTI_VALUED_FIELD_NAME, "type=geo_point", NUMBER_FIELD_NAME, "type=long", "tag", "type=string,index=not_analyzed")); + .addMapping("type", SINGLE_VALUED_FIELD_NAME, "type=geo_point", MULTI_VALUED_FIELD_NAME, "type=geo_point", NUMBER_FIELD_NAME, "type=long", "tag", "type=keyword")); GeoPoint[] geoValues = new GeoPoint[5]; geoValues[0] = new GeoPoint(38, 178); @@ -154,7 +154,7 @@ public abstract class AbstractGeoTestCase extends ESIntegTestCase { .endObject())); } assertAcked(prepareCreate(HIGH_CARD_IDX_NAME).setSettings(Settings.builder().put("number_of_shards", 2)) - .addMapping("type", SINGLE_VALUED_FIELD_NAME, "type=geo_point", MULTI_VALUED_FIELD_NAME, "type=geo_point", NUMBER_FIELD_NAME, "type=long,store=true", "tag", "type=string,index=not_analyzed")); + .addMapping("type", SINGLE_VALUED_FIELD_NAME, "type=geo_point", MULTI_VALUED_FIELD_NAME, "type=geo_point", NUMBER_FIELD_NAME, "type=long,store=true", "tag", "type=keyword")); for (int i = 0; i < 2000; i++) { singleVal = singleValues[i % numUniqueGeoPoints]; diff --git a/core/src/test/java/org/elasticsearch/search/aggregations/metrics/TopHitsIT.java b/core/src/test/java/org/elasticsearch/search/aggregations/metrics/TopHitsIT.java index 90a52ed11b8..3d8259a6ed6 100644 --- a/core/src/test/java/org/elasticsearch/search/aggregations/metrics/TopHitsIT.java +++ b/core/src/test/java/org/elasticsearch/search/aggregations/metrics/TopHitsIT.java @@ -120,8 +120,7 @@ public class TopHitsIT extends ESIntegTestCase { .field("type", "nested") .startObject("properties") .startObject("name") - .field("type", "string") - .field("index", "not_analyzed") + .field("type", "keyword") .endObject() .endObject() .endObject() diff --git a/core/src/test/java/org/elasticsearch/search/basic/SearchWithRandomExceptionsIT.java b/core/src/test/java/org/elasticsearch/search/basic/SearchWithRandomExceptionsIT.java index c45b04f7825..d342402e4bf 100644 --- a/core/src/test/java/org/elasticsearch/search/basic/SearchWithRandomExceptionsIT.java +++ b/core/src/test/java/org/elasticsearch/search/basic/SearchWithRandomExceptionsIT.java @@ -63,8 +63,7 @@ public class SearchWithRandomExceptionsIT extends ESIntegTestCase { startObject("type"). startObject("properties"). startObject("test") - .field("type", "string") - .field("index", "not_analyzed") + .field("type", "keyword") .endObject(). endObject(). endObject() diff --git a/core/src/test/java/org/elasticsearch/search/basic/SearchWithRandomIOExceptionsIT.java b/core/src/test/java/org/elasticsearch/search/basic/SearchWithRandomIOExceptionsIT.java index a6b76359cff..36e3a6076d5 100644 --- a/core/src/test/java/org/elasticsearch/search/basic/SearchWithRandomIOExceptionsIT.java +++ b/core/src/test/java/org/elasticsearch/search/basic/SearchWithRandomIOExceptionsIT.java @@ -57,8 +57,7 @@ public class SearchWithRandomIOExceptionsIT extends ESIntegTestCase { startObject("type"). startObject("properties"). startObject("test") - .field("type", "string") - .field("index", "not_analyzed") + .field("type", "keyword") .endObject(). endObject(). endObject() diff --git a/core/src/test/java/org/elasticsearch/search/query/SearchQueryIT.java b/core/src/test/java/org/elasticsearch/search/query/SearchQueryIT.java index faa6b62d2ad..fdce6f6b424 100644 --- a/core/src/test/java/org/elasticsearch/search/query/SearchQueryIT.java +++ b/core/src/test/java/org/elasticsearch/search/query/SearchQueryIT.java @@ -1524,8 +1524,7 @@ public class SearchQueryIT extends ESIntegTestCase { .field("format", "epoch_millis") .endObject() .startObject("bs") - .field("type", "string") - .field("index", "not_analyzed") + .field("type", "keyword") .endObject() .endObject() .endObject() diff --git a/core/src/test/java/org/elasticsearch/search/searchafter/SearchAfterIT.java b/core/src/test/java/org/elasticsearch/search/searchafter/SearchAfterIT.java index e4ac3b728ea..0274143a6ad 100644 --- a/core/src/test/java/org/elasticsearch/search/searchafter/SearchAfterIT.java +++ b/core/src/test/java/org/elasticsearch/search/searchafter/SearchAfterIT.java @@ -295,7 +295,7 @@ public class SearchAfterIT extends ESIntegTestCase { mappings.add("type=boolean"); } else if (types.get(i) instanceof Text) { mappings.add("field" + Integer.toString(i)); - mappings.add("type=string,index=not_analyzed"); + mappings.add("type=keyword"); } else { fail("Can't match type [" + type + "]"); } diff --git a/core/src/test/java/org/elasticsearch/search/sort/FieldSortIT.java b/core/src/test/java/org/elasticsearch/search/sort/FieldSortIT.java index 2b3093563a3..cdceb9e9951 100644 --- a/core/src/test/java/org/elasticsearch/search/sort/FieldSortIT.java +++ b/core/src/test/java/org/elasticsearch/search/sort/FieldSortIT.java @@ -187,8 +187,7 @@ public class FieldSortIT extends ESIntegTestCase { "{\"$type\": " + " {\"properties\": " + " {\"grantee\": " - + " {\"index\": " - + " \"not_analyzed\", " + + " { \"index\": \"not_analyzed\", " + " \"term_vector\": \"with_positions_offsets\", " + " \"type\": \"string\", " + " \"analyzer\": \"snowball\", " @@ -265,12 +264,10 @@ public class FieldSortIT extends ESIntegTestCase { .startObject("type") .startObject("properties") .startObject("sparse_bytes") - .field("type", "string") - .field("index", "not_analyzed") + .field("type", "keyword") .endObject() .startObject("dense_bytes") - .field("type", "string") - .field("index", "not_analyzed") + .field("type", "keyword") .endObject() .endObject() .endObject() @@ -518,7 +515,7 @@ public class FieldSortIT extends ESIntegTestCase { assertAcked(prepareCreate("test") .addMapping("type1", XContentFactory.jsonBuilder().startObject().startObject("type1").startObject("properties").startObject("str_value") - .field("type", "string").field("index", "not_analyzed").startObject("fielddata") + .field("type", "keyword").startObject("fielddata") .field("format", random().nextBoolean() ? "doc_values" : null).endObject().endObject().startObject("boolean_value") .field("type", "boolean").endObject().startObject("byte_value").field("type", "byte").startObject("fielddata") .field("format", random().nextBoolean() ? "doc_values" : null).endObject().endObject().startObject("short_value") @@ -826,8 +823,7 @@ public class FieldSortIT extends ESIntegTestCase { .startObject("type1") .startObject("properties") .startObject("value") - .field("type", "string") - .field("index", "not_analyzed") + .field("type", "keyword") .endObject() .endObject() .endObject() @@ -950,7 +946,7 @@ public class FieldSortIT extends ESIntegTestCase { .field("type", "float").startObject("fielddata").field("format", random().nextBoolean() ? "doc_values" : null) .endObject().endObject().startObject("double_values").field("type", "double").startObject("fielddata") .field("format", random().nextBoolean() ? "doc_values" : null).endObject().endObject().startObject("string_values") - .field("type", "string").field("index", "not_analyzed").startObject("fielddata") + .field("type", "keyword").startObject("fielddata") .field("format", random().nextBoolean() ? "doc_values" : null).endObject().endObject().endObject().endObject() .endObject())); ensureGreen(); @@ -1259,7 +1255,7 @@ public class FieldSortIT extends ESIntegTestCase { public void testSortOnRareField() throws IOException { assertAcked(prepareCreate("test").addMapping("type1", XContentFactory.jsonBuilder().startObject().startObject("type1").startObject("properties").startObject("string_values") - .field("type", "string").field("index", "not_analyzed").startObject("fielddata") + .field("type", "keyword").startObject("fielddata") .field("format", random().nextBoolean() ? "doc_values" : null).endObject().endObject().endObject().endObject() .endObject())); ensureGreen(); @@ -1437,8 +1433,7 @@ public class FieldSortIT extends ESIntegTestCase { .field("type", "string") .startObject("fields") .startObject("sub") - .field("type", "string") - .field("index", "not_analyzed") + .field("type", "keyword") .endObject() .endObject() .endObject() diff --git a/modules/lang-groovy/src/test/java/org/elasticsearch/messy/tests/EquivalenceTests.java b/modules/lang-groovy/src/test/java/org/elasticsearch/messy/tests/EquivalenceTests.java index 3c062f871d3..e9c2969b07c 100644 --- a/modules/lang-groovy/src/test/java/org/elasticsearch/messy/tests/EquivalenceTests.java +++ b/modules/lang-groovy/src/test/java/org/elasticsearch/messy/tests/EquivalenceTests.java @@ -188,13 +188,11 @@ public class EquivalenceTests extends ESIntegTestCase { .startObject("type") .startObject("properties") .startObject("string_values") - .field("type", "string") - .field("index", "not_analyzed") + .field("type", "keyword") .startObject("fields") .startObject("doc_values") - .field("type", "string") - .field("index", "no") - .field("doc_values", true) + .field("type", "keyword") + .field("index", false) .endObject() .endObject() .endObject() diff --git a/modules/lang-groovy/src/test/java/org/elasticsearch/messy/tests/SearchFieldsTests.java b/modules/lang-groovy/src/test/java/org/elasticsearch/messy/tests/SearchFieldsTests.java index f38b4e36e4e..1b58bde91c8 100644 --- a/modules/lang-groovy/src/test/java/org/elasticsearch/messy/tests/SearchFieldsTests.java +++ b/modules/lang-groovy/src/test/java/org/elasticsearch/messy/tests/SearchFieldsTests.java @@ -614,10 +614,10 @@ public class SearchFieldsTests extends ESIntegTestCase { public void testScriptFields() throws Exception { assertAcked(prepareCreate("index").addMapping("type", - "s", "type=string,index=not_analyzed", + "s", "type=keyword", "l", "type=long", "d", "type=double", - "ms", "type=string,index=not_analyzed", + "ms", "type=keyword", "ml", "type=long", "md", "type=double").get()); final int numDocs = randomIntBetween(3, 8); diff --git a/modules/lang-groovy/src/test/java/org/elasticsearch/messy/tests/SimpleSortTests.java b/modules/lang-groovy/src/test/java/org/elasticsearch/messy/tests/SimpleSortTests.java index 096e30f40da..48570de1a81 100644 --- a/modules/lang-groovy/src/test/java/org/elasticsearch/messy/tests/SimpleSortTests.java +++ b/modules/lang-groovy/src/test/java/org/elasticsearch/messy/tests/SimpleSortTests.java @@ -65,7 +65,7 @@ public class SimpleSortTests extends ESIntegTestCase { Random random = random(); assertAcked(prepareCreate("test") .addMapping("type1", XContentFactory.jsonBuilder().startObject().startObject("type1").startObject("properties") - .startObject("str_value").field("type", "string").field("index", "not_analyzed").startObject("fielddata").field("format", random().nextBoolean() ? "doc_values" : null).endObject().endObject() + .startObject("str_value").field("type", "keyword").startObject("fielddata").field("format", random().nextBoolean() ? "doc_values" : null).endObject().endObject() .startObject("boolean_value").field("type", "boolean").endObject() .startObject("byte_value").field("type", "byte").startObject("fielddata").field("format", random().nextBoolean() ? "doc_values" : null).endObject().endObject() .startObject("short_value").field("type", "short").startObject("fielddata").field("format", random().nextBoolean() ? "doc_values" : null).endObject().endObject() @@ -226,7 +226,7 @@ public class SimpleSortTests extends ESIntegTestCase { // We have to specify mapping explicitly because by the time search is performed dynamic mapping might not // be propagated to all nodes yet and sort operation fail when the sort field is not defined String mapping = jsonBuilder().startObject().startObject("type1").startObject("properties") - .startObject("svalue").field("type", "string").field("index", "not_analyzed").startObject("fielddata").field("format", random().nextBoolean() ? "doc_values" : null).endObject().endObject() + .startObject("svalue").field("type", "keyword").startObject("fielddata").field("format", random().nextBoolean() ? "doc_values" : null).endObject().endObject() .endObject().endObject().endObject().string(); assertAcked(prepareCreate("test").addMapping("type1", mapping)); ensureGreen(); diff --git a/rest-api-spec/src/main/resources/rest-api-spec/test/indices.put_mapping/10_basic.yaml b/rest-api-spec/src/main/resources/rest-api-spec/test/indices.put_mapping/10_basic.yaml index efdcf15cf89..2a63411937e 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/test/indices.put_mapping/10_basic.yaml +++ b/rest-api-spec/src/main/resources/rest-api-spec/test/indices.put_mapping/10_basic.yaml @@ -39,8 +39,7 @@ analyzer: whitespace fields: text_raw: - type: string - index: not_analyzed + type: keyword - do: @@ -48,4 +47,4 @@ index: test_index - match: {test_index.mappings.test_type.properties.text1.type: string} - - match: {test_index.mappings.test_type.properties.text1.fields.text_raw.index: not_analyzed} + - match: {test_index.mappings.test_type.properties.text1.fields.text_raw.type: keyword}