From 8ebd341710e0a4ace2580f5f34c5768c53c61aa8 Mon Sep 17 00:00:00 2001 From: Alan Woodward Date: Tue, 23 Jun 2020 14:37:26 +0100 Subject: [PATCH] Add text search information to MappedFieldType (#58230) (#58432) Now that MappedFieldType no longer extends lucene's FieldType, we need to have a way of getting the index information about a field necessary for building text queries, building term vectors, highlighting, etc. This commit introduces a new TextSearchInfo abstraction that holds this information, and a getTextSearchInfo() method to MappedFieldType to make it available. Field types that do not support text search can just return null here. This allows us to remove the MapperService.getLuceneFieldType() shim method. --- .../index/mapper/RankFeatureFieldMapper.java | 2 +- .../mapper/RankFeatureMetaFieldMapper.java | 2 +- .../index/mapper/RankFeaturesFieldMapper.java | 2 +- .../index/mapper/ScaledFloatFieldMapper.java | 2 +- .../mapper/SearchAsYouTypeFieldMapper.java | 46 +++---- .../mapper/SearchAsYouTypeFieldTypeTests.java | 17 ++- .../join/mapper/MetaJoinFieldMapper.java | 3 +- .../join/mapper/ParentIdFieldMapper.java | 3 +- .../join/mapper/ParentJoinFieldMapper.java | 3 +- .../percolator/PercolatorFieldMapper.java | 3 +- .../ICUCollationKeywordFieldMapper.java | 2 +- .../AnnotatedTextFieldMapper.java | 4 +- .../mapper/murmur3/Murmur3FieldMapper.java | 3 +- .../plain/StringBinaryDVLeafFieldData.java | 4 +- .../mapper/AbstractGeometryFieldMapper.java | 3 +- .../index/mapper/AllFieldMapper.java | 2 +- .../index/mapper/BinaryFieldMapper.java | 2 +- .../index/mapper/BooleanFieldMapper.java | 2 +- .../index/mapper/CompletionFieldMapper.java | 8 +- .../index/mapper/ConstantFieldType.java | 2 +- .../index/mapper/DateFieldMapper.java | 2 +- .../index/mapper/FieldNamesFieldMapper.java | 2 +- .../index/mapper/IdFieldMapper.java | 2 +- .../index/mapper/IgnoredFieldMapper.java | 2 +- .../index/mapper/IpFieldMapper.java | 2 +- .../index/mapper/KeywordFieldMapper.java | 16 ++- .../index/mapper/MappedFieldType.java | 23 ++-- .../index/mapper/MapperService.java | 15 --- .../index/mapper/NumberFieldMapper.java | 2 +- .../index/mapper/RangeFieldMapper.java | 4 +- .../index/mapper/RoutingFieldMapper.java | 2 +- .../index/mapper/SeqNoFieldMapper.java | 2 +- .../index/mapper/SimpleMappedFieldType.java | 5 +- .../index/mapper/SourceFieldMapper.java | 2 +- .../index/mapper/StringFieldType.java | 5 +- .../index/mapper/TermBasedFieldType.java | 4 +- .../index/mapper/TextFieldMapper.java | 48 ++++---- .../index/mapper/TextSearchInfo.java | 114 ++++++++++++++++++ .../index/mapper/TypeFieldMapper.java | 2 +- .../index/mapper/VersionFieldMapper.java | 2 +- .../index/query/IntervalsSourceProvider.java | 4 +- .../index/search/MatchQuery.java | 4 +- .../index/search/QueryStringQueryParser.java | 7 +- .../index/termvectors/TermVectorsService.java | 3 +- .../highlight/FastVectorHighlighter.java | 17 ++- .../subphase/highlight/HighlightPhase.java | 5 +- .../subphase/highlight/HighlightUtils.java | 6 +- .../fetch/subphase/highlight/Highlighter.java | 4 +- .../highlight/HighlighterContext.java | 5 +- .../subphase/highlight/PlainHighlighter.java | 3 +- .../highlight/UnifiedHighlighter.java | 21 ++-- .../index/mapper/DateFieldMapperTests.java | 3 +- .../mapper/DocumentFieldMapperTests.java | 2 +- .../index/mapper/ExternalMapper.java | 2 +- .../index/mapper/FakeStringFieldMapper.java | 2 +- .../GenericStoreDynamicTemplateTests.java | 7 +- .../mapper/JavaMultiFieldMergeTests.java | 17 ++- .../index/mapper/MultiFieldTests.java | 29 ++--- .../mapper/PathMatchDynamicTemplateTests.java | 14 +-- .../index/mapper/TextFieldTypeTests.java | 12 +- .../index/query/ExistsQueryBuilderTests.java | 2 +- .../query/QueryStringQueryBuilderTests.java | 4 +- .../index/query/RangeQueryBuilderTests.java | 3 +- .../search/collapse/CollapseBuilderTests.java | 3 +- .../subphase/highlight/CustomHighlighter.java | 4 +- .../search/slice/SliceBuilderTests.java | 3 +- .../index/mapper/MockFieldMapper.java | 2 +- .../mapper/HistogramFieldMapper.java | 3 +- .../mapper/FlatObjectFieldMapper.java | 5 +- .../mapper/DenseVectorFieldMapper.java | 3 +- .../mapper/SparseVectorFieldMapper.java | 3 +- .../wildcard/mapper/WildcardFieldMapper.java | 7 +- .../mapper/WildcardFieldTypeTests.java | 2 +- 73 files changed, 344 insertions(+), 238 deletions(-) create mode 100644 server/src/main/java/org/elasticsearch/index/mapper/TextSearchInfo.java diff --git a/modules/mapper-extras/src/main/java/org/elasticsearch/index/mapper/RankFeatureFieldMapper.java b/modules/mapper-extras/src/main/java/org/elasticsearch/index/mapper/RankFeatureFieldMapper.java index 954b8f12bec..93f7cb4230b 100644 --- a/modules/mapper-extras/src/main/java/org/elasticsearch/index/mapper/RankFeatureFieldMapper.java +++ b/modules/mapper-extras/src/main/java/org/elasticsearch/index/mapper/RankFeatureFieldMapper.java @@ -98,7 +98,7 @@ public class RankFeatureFieldMapper extends FieldMapper { private final boolean positiveScoreImpact; public RankFeatureFieldType(String name, Map meta, boolean positiveScoreImpact) { - super(name, true, false, meta); + super(name, true, false, TextSearchInfo.NONE, meta); this.positiveScoreImpact = positiveScoreImpact; setIndexAnalyzer(Lucene.KEYWORD_ANALYZER); setSearchAnalyzer(Lucene.KEYWORD_ANALYZER); diff --git a/modules/mapper-extras/src/main/java/org/elasticsearch/index/mapper/RankFeatureMetaFieldMapper.java b/modules/mapper-extras/src/main/java/org/elasticsearch/index/mapper/RankFeatureMetaFieldMapper.java index 0b38be92aa7..78652fb0fc1 100644 --- a/modules/mapper-extras/src/main/java/org/elasticsearch/index/mapper/RankFeatureMetaFieldMapper.java +++ b/modules/mapper-extras/src/main/java/org/elasticsearch/index/mapper/RankFeatureMetaFieldMapper.java @@ -89,7 +89,7 @@ public class RankFeatureMetaFieldMapper extends MetadataFieldMapper { public static final RankFeatureMetaFieldType INSTANCE = new RankFeatureMetaFieldType(); private RankFeatureMetaFieldType() { - super(NAME, false, false, Collections.emptyMap()); + super(NAME, false, false, TextSearchInfo.NONE, Collections.emptyMap()); } protected RankFeatureMetaFieldType(RankFeatureMetaFieldType ref) { diff --git a/modules/mapper-extras/src/main/java/org/elasticsearch/index/mapper/RankFeaturesFieldMapper.java b/modules/mapper-extras/src/main/java/org/elasticsearch/index/mapper/RankFeaturesFieldMapper.java index fca28f88490..b41bc86aa9a 100644 --- a/modules/mapper-extras/src/main/java/org/elasticsearch/index/mapper/RankFeaturesFieldMapper.java +++ b/modules/mapper-extras/src/main/java/org/elasticsearch/index/mapper/RankFeaturesFieldMapper.java @@ -76,7 +76,7 @@ public class RankFeaturesFieldMapper extends FieldMapper { public static final class RankFeaturesFieldType extends MappedFieldType { public RankFeaturesFieldType(String name, Map meta) { - super(name, false, false, meta); + super(name, false, false, TextSearchInfo.NONE, meta); setIndexAnalyzer(Lucene.KEYWORD_ANALYZER); setSearchAnalyzer(Lucene.KEYWORD_ANALYZER); } diff --git a/modules/mapper-extras/src/main/java/org/elasticsearch/index/mapper/ScaledFloatFieldMapper.java b/modules/mapper-extras/src/main/java/org/elasticsearch/index/mapper/ScaledFloatFieldMapper.java index b92d5c6780f..88c55c95540 100644 --- a/modules/mapper-extras/src/main/java/org/elasticsearch/index/mapper/ScaledFloatFieldMapper.java +++ b/modules/mapper-extras/src/main/java/org/elasticsearch/index/mapper/ScaledFloatFieldMapper.java @@ -185,7 +185,7 @@ public class ScaledFloatFieldMapper extends FieldMapper { private final double scalingFactor; public ScaledFloatFieldType(String name, boolean indexed, boolean hasDocValues, Map meta, double scalingFactor) { - super(name, indexed, hasDocValues, meta); + super(name, indexed, hasDocValues, TextSearchInfo.SIMPLE_MATCH_ONLY, meta); this.scalingFactor = scalingFactor; } diff --git a/modules/mapper-extras/src/main/java/org/elasticsearch/index/mapper/SearchAsYouTypeFieldMapper.java b/modules/mapper-extras/src/main/java/org/elasticsearch/index/mapper/SearchAsYouTypeFieldMapper.java index 423ed1027cf..62b1114c74a 100644 --- a/modules/mapper-extras/src/main/java/org/elasticsearch/index/mapper/SearchAsYouTypeFieldMapper.java +++ b/modules/mapper-extras/src/main/java/org/elasticsearch/index/mapper/SearchAsYouTypeFieldMapper.java @@ -157,16 +157,19 @@ public class SearchAsYouTypeFieldMapper extends FieldMapper { @Override public SearchAsYouTypeFieldMapper build(Mapper.BuilderContext context) { - boolean hasNorms = fieldType.omitNorms() == false; - SearchAsYouTypeFieldType ft = new SearchAsYouTypeFieldType(buildFullName(context), indexed, meta, hasNorms); + SearchAsYouTypeFieldType ft = new SearchAsYouTypeFieldType(buildFullName(context), fieldType, meta); ft.setIndexAnalyzer(indexAnalyzer); ft.setSearchAnalyzer(searchAnalyzer); ft.setSearchQuoteAnalyzer(searchQuoteAnalyzer); ft.setSimilarity(similarity); // set up the prefix field + FieldType prefixft = new FieldType(fieldType); + prefixft.setStoreTermVectors(false); + prefixft.setOmitNorms(true); + prefixft.setStored(false); final String fullName = buildFullName(context); - final PrefixFieldType prefixFieldType = new PrefixFieldType(fullName, Defaults.MIN_GRAM, Defaults.MAX_GRAM); + final PrefixFieldType prefixFieldType = new PrefixFieldType(fullName, prefixft, Defaults.MIN_GRAM, Defaults.MAX_GRAM); // wrap the root field's index analyzer with shingles and edge ngrams final SearchAsYouTypeAnalyzer prefixIndexWrapper = SearchAsYouTypeAnalyzer.withShingleAndPrefix(indexAnalyzer.analyzer(), maxShingleSize); @@ -176,10 +179,6 @@ public class SearchAsYouTypeFieldMapper extends FieldMapper { // don't wrap the root field's search quote analyzer as prefix field doesn't support phrase queries prefixFieldType.setIndexAnalyzer(new NamedAnalyzer(indexAnalyzer.name(), AnalyzerScope.INDEX, prefixIndexWrapper)); prefixFieldType.setSearchAnalyzer(new NamedAnalyzer(searchAnalyzer.name(), AnalyzerScope.INDEX, prefixSearchWrapper)); - FieldType prefixft = new FieldType(fieldType); - prefixft.setStoreTermVectors(false); - prefixft.setOmitNorms(true); - prefixft.setStored(false); final PrefixFieldMapper prefixFieldMapper = new PrefixFieldMapper(prefixft, prefixFieldType); // set up the shingle fields @@ -187,8 +186,10 @@ public class SearchAsYouTypeFieldMapper extends FieldMapper { final ShingleFieldType[] shingleFieldTypes = new ShingleFieldType[maxShingleSize - 1]; for (int i = 0; i < shingleFieldMappers.length; i++) { final int shingleSize = i + 2; + FieldType shingleft = new FieldType(fieldType); + shingleft.setStored(false); String fieldName = getShingleFieldName(buildFullName(context), shingleSize); - final ShingleFieldType shingleFieldType = new ShingleFieldType(fieldName, shingleSize, hasNorms); + final ShingleFieldType shingleFieldType = new ShingleFieldType(fieldName, shingleSize, shingleft); // wrap the root field's index, search, and search quote analyzers with shingles final SearchAsYouTypeAnalyzer shingleIndexWrapper = SearchAsYouTypeAnalyzer.withShingle(indexAnalyzer.analyzer(), shingleSize); @@ -202,8 +203,6 @@ public class SearchAsYouTypeFieldMapper extends FieldMapper { new NamedAnalyzer(searchQuoteAnalyzer.name(), AnalyzerScope.INDEX, shingleSearchQuoteWrapper)); shingleFieldType.setPrefixFieldType(prefixFieldType); shingleFieldTypes[i] = shingleFieldType; - FieldType shingleft = new FieldType(fieldType); - shingleft.setStored(false); shingleFieldMappers[i] = new ShingleFieldMapper(shingleft, shingleFieldType); } ft.setPrefixField(prefixFieldType); @@ -235,12 +234,9 @@ public class SearchAsYouTypeFieldMapper extends FieldMapper { PrefixFieldType prefixField; ShingleFieldType[] shingleFields = new ShingleFieldType[0]; - final boolean hasNorms; - SearchAsYouTypeFieldType(String name, boolean indexed, Map meta, boolean hasNorms) { - super(name, indexed, false, meta); - this.hasNorms = hasNorms; - this.hasPositions = true; + SearchAsYouTypeFieldType(String name, FieldType fieldType, Map meta) { + super(name, fieldType.indexOptions() != IndexOptions.NONE, false, new TextSearchInfo(fieldType), meta); } SearchAsYouTypeFieldType(SearchAsYouTypeFieldType other) { @@ -257,7 +253,6 @@ public class SearchAsYouTypeFieldMapper extends FieldMapper { } } } - this.hasNorms = other.hasNorms; } public void setPrefixField(PrefixFieldType prefixField) { @@ -285,7 +280,7 @@ public class SearchAsYouTypeFieldMapper extends FieldMapper { @Override public Query existsQuery(QueryShardContext context) { - if (hasNorms == false) { + if (getTextSearchInfo().hasNorms() == false) { return new TermQuery(new Term(FieldNamesFieldMapper.NAME, name())); } else { return new NormsFieldExistsQuery(name()); @@ -386,12 +381,11 @@ public class SearchAsYouTypeFieldMapper extends FieldMapper { final int maxChars; final String parentField; - PrefixFieldType(String parentField, int minChars, int maxChars) { - super(parentField + PREFIX_FIELD_SUFFIX, true, false, Collections.emptyMap()); + PrefixFieldType(String parentField, FieldType fieldType, int minChars, int maxChars) { + super(parentField + PREFIX_FIELD_SUFFIX, true, false, new TextSearchInfo(fieldType), Collections.emptyMap()); this.minChars = minChars; this.maxChars = maxChars; this.parentField = parentField; - this.hasPositions = true; } PrefixFieldType(PrefixFieldType other) { @@ -399,7 +393,6 @@ public class SearchAsYouTypeFieldMapper extends FieldMapper { this.minChars = other.minChars; this.maxChars = other.maxChars; this.parentField = other.parentField; - this.hasPositions = other.hasPositions; } boolean termLengthWithinBounds(int length) { @@ -539,21 +532,16 @@ public class SearchAsYouTypeFieldMapper extends FieldMapper { */ static class ShingleFieldType extends StringFieldType { final int shingleSize; - final boolean hasNorms; PrefixFieldType prefixFieldType; - ShingleFieldType(String name, int shingleSize, boolean hasNorms) { - super(name, true, false, Collections.emptyMap()); + ShingleFieldType(String name, int shingleSize, FieldType fieldType) { + super(name, true, false, new TextSearchInfo(fieldType), Collections.emptyMap()); this.shingleSize = shingleSize; - this.hasNorms = hasNorms; - this.hasPositions = true; } ShingleFieldType(ShingleFieldType other) { super(other); this.shingleSize = other.shingleSize; - this.hasNorms = other.hasNorms; - this.hasPositions = other.hasPositions; if (other.prefixFieldType != null) { this.prefixFieldType = other.prefixFieldType.clone(); } @@ -575,7 +563,7 @@ public class SearchAsYouTypeFieldMapper extends FieldMapper { @Override public Query existsQuery(QueryShardContext context) { - if (hasNorms == false) { + if (getTextSearchInfo().hasNorms() == false) { return new TermQuery(new Term(FieldNamesFieldMapper.NAME, name())); } else { return new NormsFieldExistsQuery(name()); diff --git a/modules/mapper-extras/src/test/java/org/elasticsearch/index/mapper/SearchAsYouTypeFieldTypeTests.java b/modules/mapper-extras/src/test/java/org/elasticsearch/index/mapper/SearchAsYouTypeFieldTypeTests.java index 184155413e1..0d043590bc3 100644 --- a/modules/mapper-extras/src/test/java/org/elasticsearch/index/mapper/SearchAsYouTypeFieldTypeTests.java +++ b/modules/mapper-extras/src/test/java/org/elasticsearch/index/mapper/SearchAsYouTypeFieldTypeTests.java @@ -19,6 +19,8 @@ package org.elasticsearch.index.mapper; +import org.apache.lucene.document.FieldType; +import org.apache.lucene.index.IndexOptions; import org.apache.lucene.index.Term; import org.apache.lucene.search.ConstantScoreQuery; import org.apache.lucene.search.PrefixQuery; @@ -41,12 +43,17 @@ import static org.hamcrest.Matchers.equalTo; public class SearchAsYouTypeFieldTypeTests extends FieldTypeTestCase { private static final String NAME = "a_field"; + private static final FieldType UNSEARCHABLE = new FieldType(); + static { + UNSEARCHABLE.setIndexOptions(IndexOptions.NONE); + UNSEARCHABLE.freeze(); + } @Override protected SearchAsYouTypeFieldType createDefaultFieldType(String name, Map meta) { - final SearchAsYouTypeFieldType fieldType = new SearchAsYouTypeFieldType(name, true, meta, true); - fieldType.setPrefixField(new PrefixFieldType(NAME, Defaults.MIN_GRAM, Defaults.MAX_GRAM)); - fieldType.setShingleFields(new ShingleFieldType[] { new ShingleFieldType(fieldType.name(), 2, true) }); + final SearchAsYouTypeFieldType fieldType = new SearchAsYouTypeFieldType(name, Defaults.FIELD_TYPE, meta); + fieldType.setPrefixField(new PrefixFieldType(NAME, Defaults.FIELD_TYPE, Defaults.MIN_GRAM, Defaults.MAX_GRAM)); + fieldType.setShingleFields(new ShingleFieldType[] { new ShingleFieldType(fieldType.name(), 2, Defaults.FIELD_TYPE) }); return fieldType; } @@ -55,7 +62,7 @@ public class SearchAsYouTypeFieldTypeTests extends FieldTypeTestCase unsearchable.termQuery("foo", null)); assertThat(e.getMessage(), equalTo("Cannot search on field [" + NAME + "] since it is not indexed.")); } @@ -66,7 +73,7 @@ public class SearchAsYouTypeFieldTypeTests extends FieldTypeTestCase unsearchable.termsQuery(asList("foo", "bar"), null)); assertThat(e.getMessage(), equalTo("Cannot search on field [" + NAME + "] since it is not indexed.")); diff --git a/modules/parent-join/src/main/java/org/elasticsearch/join/mapper/MetaJoinFieldMapper.java b/modules/parent-join/src/main/java/org/elasticsearch/join/mapper/MetaJoinFieldMapper.java index 73df7164b9f..1fc0709f16e 100644 --- a/modules/parent-join/src/main/java/org/elasticsearch/join/mapper/MetaJoinFieldMapper.java +++ b/modules/parent-join/src/main/java/org/elasticsearch/join/mapper/MetaJoinFieldMapper.java @@ -28,6 +28,7 @@ import org.elasticsearch.index.fielddata.plain.SortedSetOrdinalsIndexFieldData; import org.elasticsearch.index.mapper.FieldMapper; import org.elasticsearch.index.mapper.ParseContext; import org.elasticsearch.index.mapper.StringFieldType; +import org.elasticsearch.index.mapper.TextSearchInfo; import org.elasticsearch.index.query.QueryShardContext; import org.elasticsearch.search.aggregations.support.CoreValuesSourceType; @@ -77,7 +78,7 @@ public class MetaJoinFieldMapper extends FieldMapper { private final String joinField; MetaJoinFieldType(String joinField) { - super(NAME, false, false, Collections.emptyMap()); + super(NAME, false, false, TextSearchInfo.SIMPLE_MATCH_ONLY, Collections.emptyMap()); this.joinField = joinField; } diff --git a/modules/parent-join/src/main/java/org/elasticsearch/join/mapper/ParentIdFieldMapper.java b/modules/parent-join/src/main/java/org/elasticsearch/join/mapper/ParentIdFieldMapper.java index 1a130ae297e..6763e88c168 100644 --- a/modules/parent-join/src/main/java/org/elasticsearch/join/mapper/ParentIdFieldMapper.java +++ b/modules/parent-join/src/main/java/org/elasticsearch/join/mapper/ParentIdFieldMapper.java @@ -38,6 +38,7 @@ import org.elasticsearch.index.mapper.FieldMapper; import org.elasticsearch.index.mapper.MappedFieldType; import org.elasticsearch.index.mapper.ParseContext; import org.elasticsearch.index.mapper.StringFieldType; +import org.elasticsearch.index.mapper.TextSearchInfo; import org.elasticsearch.index.query.QueryShardContext; import org.elasticsearch.search.aggregations.support.CoreValuesSourceType; @@ -94,7 +95,7 @@ public final class ParentIdFieldMapper extends FieldMapper { public static final class ParentIdFieldType extends StringFieldType { ParentIdFieldType(String name, boolean eagerGlobalOrdinals, Map meta) { - super(name, true, true, meta); + super(name, true, true, TextSearchInfo.SIMPLE_MATCH_ONLY, meta); setIndexAnalyzer(Lucene.KEYWORD_ANALYZER); setSearchAnalyzer(Lucene.KEYWORD_ANALYZER); setEagerGlobalOrdinals(eagerGlobalOrdinals); diff --git a/modules/parent-join/src/main/java/org/elasticsearch/join/mapper/ParentJoinFieldMapper.java b/modules/parent-join/src/main/java/org/elasticsearch/join/mapper/ParentJoinFieldMapper.java index 770331dc8e8..54a849b6464 100644 --- a/modules/parent-join/src/main/java/org/elasticsearch/join/mapper/ParentJoinFieldMapper.java +++ b/modules/parent-join/src/main/java/org/elasticsearch/join/mapper/ParentJoinFieldMapper.java @@ -43,6 +43,7 @@ import org.elasticsearch.index.mapper.MapperParsingException; import org.elasticsearch.index.mapper.MapperService; import org.elasticsearch.index.mapper.ParseContext; import org.elasticsearch.index.mapper.StringFieldType; +import org.elasticsearch.index.mapper.TextSearchInfo; import org.elasticsearch.index.query.QueryShardContext; import org.elasticsearch.search.aggregations.support.CoreValuesSourceType; @@ -205,7 +206,7 @@ public final class ParentJoinFieldMapper extends FieldMapper { public static final class JoinFieldType extends StringFieldType { public JoinFieldType(String name, Map meta) { - super(name, true, true, meta); + super(name, true, true, TextSearchInfo.SIMPLE_MATCH_ONLY, meta); setIndexAnalyzer(Lucene.KEYWORD_ANALYZER); setSearchAnalyzer(Lucene.KEYWORD_ANALYZER); } diff --git a/modules/percolator/src/main/java/org/elasticsearch/percolator/PercolatorFieldMapper.java b/modules/percolator/src/main/java/org/elasticsearch/percolator/PercolatorFieldMapper.java index b3692e96049..ac3d1136c5f 100644 --- a/modules/percolator/src/main/java/org/elasticsearch/percolator/PercolatorFieldMapper.java +++ b/modules/percolator/src/main/java/org/elasticsearch/percolator/PercolatorFieldMapper.java @@ -69,6 +69,7 @@ import org.elasticsearch.index.mapper.NumberFieldMapper; import org.elasticsearch.index.mapper.ParseContext; import org.elasticsearch.index.mapper.RangeFieldMapper; import org.elasticsearch.index.mapper.RangeType; +import org.elasticsearch.index.mapper.TextSearchInfo; import org.elasticsearch.index.query.BoolQueryBuilder; import org.elasticsearch.index.query.BoostingQueryBuilder; import org.elasticsearch.index.query.ConstantScoreQueryBuilder; @@ -202,7 +203,7 @@ public class PercolatorFieldMapper extends FieldMapper { boolean mapUnmappedFieldsAsText; PercolatorFieldType(String name, Map meta) { - super(name, false, false, meta); + super(name, false, false, TextSearchInfo.NONE, meta); } PercolatorFieldType(PercolatorFieldType ref) { diff --git a/plugins/analysis-icu/src/main/java/org/elasticsearch/index/mapper/ICUCollationKeywordFieldMapper.java b/plugins/analysis-icu/src/main/java/org/elasticsearch/index/mapper/ICUCollationKeywordFieldMapper.java index df44b8aaad4..6c0aa7b4ddc 100644 --- a/plugins/analysis-icu/src/main/java/org/elasticsearch/index/mapper/ICUCollationKeywordFieldMapper.java +++ b/plugins/analysis-icu/src/main/java/org/elasticsearch/index/mapper/ICUCollationKeywordFieldMapper.java @@ -77,7 +77,7 @@ public class ICUCollationKeywordFieldMapper extends FieldMapper { private final Collator collator; public CollationFieldType(String name, boolean isSearchable, boolean hasDocValues, Collator collator, Map meta) { - super(name, isSearchable, hasDocValues, meta); + super(name, isSearchable, hasDocValues, TextSearchInfo.SIMPLE_MATCH_ONLY, meta); setIndexAnalyzer(Lucene.KEYWORD_ANALYZER); setSearchAnalyzer(Lucene.KEYWORD_ANALYZER); this.collator = collator; diff --git a/plugins/mapper-annotated-text/src/main/java/org/elasticsearch/index/mapper/annotatedtext/AnnotatedTextFieldMapper.java b/plugins/mapper-annotated-text/src/main/java/org/elasticsearch/index/mapper/annotatedtext/AnnotatedTextFieldMapper.java index 7cfe86abaf2..e48315c5901 100644 --- a/plugins/mapper-annotated-text/src/main/java/org/elasticsearch/index/mapper/annotatedtext/AnnotatedTextFieldMapper.java +++ b/plugins/mapper-annotated-text/src/main/java/org/elasticsearch/index/mapper/annotatedtext/AnnotatedTextFieldMapper.java @@ -124,7 +124,7 @@ public class AnnotatedTextFieldMapper extends FieldMapper { } else { //Using the analyzer's default BUT need to do the same thing AnalysisRegistry.processAnalyzerFactory // does to splice in new default of posIncGap=100 by wrapping the analyzer - if (fieldType.indexOptions().compareTo(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS) >= 0) { + if (hasPositions) { int overrideInc = TextFieldMapper.Defaults.POSITION_INCREMENT_GAP; ft.setIndexAnalyzer(indexAnalyzer, overrideInc); ft.setSearchAnalyzer(new NamedAnalyzer(searchAnalyzer, overrideInc)); @@ -522,7 +522,7 @@ public class AnnotatedTextFieldMapper extends FieldMapper { public static final class AnnotatedTextFieldType extends TextFieldMapper.TextFieldType { public AnnotatedTextFieldType(String name, boolean hasPositions, Map meta) { - super(name, true, hasPositions, meta); + super(name, hasPositions, meta); } protected AnnotatedTextFieldType(AnnotatedTextFieldType ref) { diff --git a/plugins/mapper-murmur3/src/main/java/org/elasticsearch/index/mapper/murmur3/Murmur3FieldMapper.java b/plugins/mapper-murmur3/src/main/java/org/elasticsearch/index/mapper/murmur3/Murmur3FieldMapper.java index 37fe6faf5c1..0dd9b5fe76f 100644 --- a/plugins/mapper-murmur3/src/main/java/org/elasticsearch/index/mapper/murmur3/Murmur3FieldMapper.java +++ b/plugins/mapper-murmur3/src/main/java/org/elasticsearch/index/mapper/murmur3/Murmur3FieldMapper.java @@ -35,6 +35,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.TextSearchInfo; import org.elasticsearch.index.mapper.TypeParsers; import org.elasticsearch.index.query.QueryShardContext; import org.elasticsearch.index.query.QueryShardException; @@ -92,7 +93,7 @@ public class Murmur3FieldMapper extends FieldMapper { // this only exists so a check can be done to match the field type to using murmur3 hashing... public static class Murmur3FieldType extends MappedFieldType { public Murmur3FieldType(String name, Map meta) { - super(name, false, true, meta); + super(name, false, true, TextSearchInfo.SIMPLE_MATCH_ONLY, meta); } protected Murmur3FieldType(Murmur3FieldType ref) { diff --git a/server/src/main/java/org/elasticsearch/index/fielddata/plain/StringBinaryDVLeafFieldData.java b/server/src/main/java/org/elasticsearch/index/fielddata/plain/StringBinaryDVLeafFieldData.java index a48a15e45d9..97678efbc8d 100644 --- a/server/src/main/java/org/elasticsearch/index/fielddata/plain/StringBinaryDVLeafFieldData.java +++ b/server/src/main/java/org/elasticsearch/index/fielddata/plain/StringBinaryDVLeafFieldData.java @@ -22,7 +22,7 @@ package org.elasticsearch.index.fielddata.plain; import org.apache.lucene.index.BinaryDocValues; import org.elasticsearch.index.fielddata.ScriptDocValues; -final class StringBinaryDVLeafFieldData extends AbstractBinaryDVLeafFieldData{ +final class StringBinaryDVLeafFieldData extends AbstractBinaryDVLeafFieldData { StringBinaryDVLeafFieldData(BinaryDocValues values) { super(values); } @@ -31,4 +31,4 @@ final class StringBinaryDVLeafFieldData extends AbstractBinaryDVLeafFieldData{ public ScriptDocValues getScriptValues() { return new ScriptDocValues.Strings(getBytesValues()); } -} \ No newline at end of file +} diff --git a/server/src/main/java/org/elasticsearch/index/mapper/AbstractGeometryFieldMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/AbstractGeometryFieldMapper.java index b29a592186b..f96fd9269d8 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/AbstractGeometryFieldMapper.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/AbstractGeometryFieldMapper.java @@ -175,7 +175,6 @@ public abstract class AbstractGeometryFieldMapper extends Fie } @Override - @SuppressWarnings("rawtypes") public T parse(String name, Map node, ParserContext parserContext) throws MapperParsingException { Map params = new HashMap<>(); @@ -189,7 +188,7 @@ public abstract class AbstractGeometryFieldMapper extends Fie protected QueryProcessor geometryQueryBuilder; protected AbstractGeometryFieldType(String name, boolean indexed, boolean hasDocValues, Map meta) { - super(name, indexed, hasDocValues, meta); + super(name, indexed, hasDocValues, TextSearchInfo.SIMPLE_MATCH_ONLY, meta); } protected AbstractGeometryFieldType(AbstractGeometryFieldType ref) { diff --git a/server/src/main/java/org/elasticsearch/index/mapper/AllFieldMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/AllFieldMapper.java index da8995303e4..30c957cc00b 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/AllFieldMapper.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/AllFieldMapper.java @@ -99,7 +99,7 @@ public class AllFieldMapper extends MetadataFieldMapper { static final class AllFieldType extends StringFieldType { AllFieldType() { - super(NAME, false, false, Collections.emptyMap()); + super(NAME, false, false, TextSearchInfo.NONE, Collections.emptyMap()); } protected AllFieldType(AllFieldType ref) { diff --git a/server/src/main/java/org/elasticsearch/index/mapper/BinaryFieldMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/BinaryFieldMapper.java index 08cad1e73f9..0b82f4f5bfb 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/BinaryFieldMapper.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/BinaryFieldMapper.java @@ -99,7 +99,7 @@ public class BinaryFieldMapper extends FieldMapper { public static final class BinaryFieldType extends MappedFieldType { public BinaryFieldType(String name, boolean hasDocValues, Map meta) { - super(name, false, hasDocValues, meta); + super(name, false, hasDocValues, TextSearchInfo.NONE, meta); } public BinaryFieldType(String name) { diff --git a/server/src/main/java/org/elasticsearch/index/mapper/BooleanFieldMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/BooleanFieldMapper.java index 8d359f3baf5..9a3894bea5e 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/BooleanFieldMapper.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/BooleanFieldMapper.java @@ -118,7 +118,7 @@ public class BooleanFieldMapper extends FieldMapper { public static final class BooleanFieldType extends TermBasedFieldType { public BooleanFieldType(String name, boolean isSearchable, boolean hasDocValues, Map meta) { - super(name, isSearchable, hasDocValues, meta); + super(name, isSearchable, hasDocValues, TextSearchInfo.SIMPLE_MATCH_ONLY, meta); } public BooleanFieldType(String name) { diff --git a/server/src/main/java/org/elasticsearch/index/mapper/CompletionFieldMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/CompletionFieldMapper.java index f62730c92ce..6e40d6ec174 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/CompletionFieldMapper.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/CompletionFieldMapper.java @@ -194,12 +194,12 @@ public class CompletionFieldMapper extends FieldMapper { private boolean preservePositionIncrements = Defaults.DEFAULT_POSITION_INCREMENTS; private ContextMappings contextMappings = null; - public CompletionFieldType(String name, Map meta) { - super(name, true, false, meta); + public CompletionFieldType(String name, FieldType luceneFieldType, Map meta) { + super(name, true, false, new TextSearchInfo(luceneFieldType), meta); } public CompletionFieldType(String name) { - this(name, Collections.emptyMap()); + this(name, Defaults.FIELD_TYPE, Collections.emptyMap()); } private CompletionFieldType(CompletionFieldType ref) { @@ -395,7 +395,7 @@ public class CompletionFieldMapper extends FieldMapper { @Override public CompletionFieldMapper build(BuilderContext context) { checkCompletionContextsLimit(context); - CompletionFieldType ft = new CompletionFieldType(buildFullName(context), meta); + CompletionFieldType ft = new CompletionFieldType(buildFullName(context), this.fieldType, meta); ft.setContextMappings(contextMappings); ft.setPreservePositionIncrements(preservePositionIncrements); ft.setPreserveSep(preserveSeparators); diff --git a/server/src/main/java/org/elasticsearch/index/mapper/ConstantFieldType.java b/server/src/main/java/org/elasticsearch/index/mapper/ConstantFieldType.java index c39994d7ef0..e7f7503a509 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/ConstantFieldType.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/ConstantFieldType.java @@ -42,7 +42,7 @@ import java.util.Map; public abstract class ConstantFieldType extends MappedFieldType { public ConstantFieldType(String name, Map meta) { - super(name, true, true, meta); + super(name, true, true, TextSearchInfo.SIMPLE_MATCH_ONLY, meta); } public ConstantFieldType(ConstantFieldType other) { diff --git a/server/src/main/java/org/elasticsearch/index/mapper/DateFieldMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/DateFieldMapper.java index d2ff790ac98..8f3e825221c 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/DateFieldMapper.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/DateFieldMapper.java @@ -308,7 +308,7 @@ public final class DateFieldMapper extends FieldMapper { public DateFieldType(String name, boolean isSearchable, boolean hasDocValues, DateFormatter dateTimeFormatter, Resolution resolution, Map meta) { - super(name, isSearchable, hasDocValues, meta); + super(name, isSearchable, hasDocValues, TextSearchInfo.SIMPLE_MATCH_ONLY, meta); this.dateTimeFormatter = dateTimeFormatter; this.dateMathParser = dateTimeFormatter.toDateMathParser(); this.resolution = resolution; diff --git a/server/src/main/java/org/elasticsearch/index/mapper/FieldNamesFieldMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/FieldNamesFieldMapper.java index d0e3f0c4b42..2a5a47ce7e5 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/FieldNamesFieldMapper.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/FieldNamesFieldMapper.java @@ -132,7 +132,7 @@ public class FieldNamesFieldMapper extends MetadataFieldMapper { private boolean enabled = Defaults.ENABLED; public FieldNamesFieldType() { - super(Defaults.NAME, true, false, Collections.emptyMap()); + super(Defaults.NAME, true, false, TextSearchInfo.SIMPLE_MATCH_ONLY, Collections.emptyMap()); } protected FieldNamesFieldType(FieldNamesFieldType ref) { diff --git a/server/src/main/java/org/elasticsearch/index/mapper/IdFieldMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/IdFieldMapper.java index c1482090489..e26c956f2c1 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/IdFieldMapper.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/IdFieldMapper.java @@ -117,7 +117,7 @@ public class IdFieldMapper extends MetadataFieldMapper { public static final IdFieldType INSTANCE = new IdFieldType(); private IdFieldType() { - super(NAME, true, false, Collections.emptyMap()); + super(NAME, true, false, TextSearchInfo.SIMPLE_MATCH_ONLY, Collections.emptyMap()); setIndexAnalyzer(Lucene.KEYWORD_ANALYZER); setSearchAnalyzer(Lucene.KEYWORD_ANALYZER); } diff --git a/server/src/main/java/org/elasticsearch/index/mapper/IgnoredFieldMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/IgnoredFieldMapper.java index 585da23d644..4a7cc78f1fe 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/IgnoredFieldMapper.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/IgnoredFieldMapper.java @@ -84,7 +84,7 @@ public final class IgnoredFieldMapper extends MetadataFieldMapper { public static final IgnoredFieldType INSTANCE = new IgnoredFieldType(); private IgnoredFieldType() { - super(NAME, true, false, Collections.emptyMap()); + super(NAME, true, false, TextSearchInfo.SIMPLE_MATCH_ONLY, Collections.emptyMap()); } protected IgnoredFieldType(IgnoredFieldType ref) { diff --git a/server/src/main/java/org/elasticsearch/index/mapper/IpFieldMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/IpFieldMapper.java index a7f56be1787..d836bc0284e 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/IpFieldMapper.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/IpFieldMapper.java @@ -141,7 +141,7 @@ public class IpFieldMapper extends FieldMapper { public static final class IpFieldType extends SimpleMappedFieldType { public IpFieldType(String name, boolean indexed, boolean hasDocValues, Map meta) { - super(name, indexed, hasDocValues, meta); + super(name, indexed, hasDocValues, TextSearchInfo.SIMPLE_MATCH_ONLY, meta); } public IpFieldType(String name) { diff --git a/server/src/main/java/org/elasticsearch/index/mapper/KeywordFieldMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/KeywordFieldMapper.java index 23562801cd5..5e6c3d9c2b3 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/KeywordFieldMapper.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/KeywordFieldMapper.java @@ -165,7 +165,7 @@ public final class KeywordFieldMapper extends FieldMapper { // TODO should this be a Lucene global analyzer as well? searchAnalyzer = new NamedAnalyzer("whitespace", AnalyzerScope.INDEX, new WhitespaceAnalyzer()); } - return new KeywordFieldType(buildFullName(context), indexed, hasDocValues, fieldType.omitNorms() == false, + return new KeywordFieldType(buildFullName(context), hasDocValues, fieldType, eagerGlobalOrdinals, normalizer, searchAnalyzer, similarity, meta, boost); } @@ -219,11 +219,12 @@ public final class KeywordFieldMapper extends FieldMapper { boolean hasNorms; - public KeywordFieldType(String name, boolean isSearchable, boolean hasDocValues, boolean hasNorms, + public KeywordFieldType(String name, boolean hasDocValues, FieldType fieldType, boolean eagerGlobalOrdinals, NamedAnalyzer normalizer, NamedAnalyzer searchAnalyzer, SimilarityProvider similarity, Map meta, float boost) { - super(name, isSearchable, hasDocValues, meta); - this.hasNorms = hasNorms; + super(name, fieldType.indexOptions() != IndexOptions.NONE, + hasDocValues, new TextSearchInfo(fieldType), meta); + this.hasNorms = fieldType.omitNorms() == false; setEagerGlobalOrdinals(eagerGlobalOrdinals); setIndexAnalyzer(normalizer); setSearchAnalyzer(searchAnalyzer); @@ -232,11 +233,14 @@ public final class KeywordFieldMapper extends FieldMapper { } public KeywordFieldType(String name, boolean isSearchable, boolean hasDocValues, Map meta) { - this(name, isSearchable, hasDocValues, true, false, Lucene.KEYWORD_ANALYZER, Lucene.KEYWORD_ANALYZER, null, meta, 1.0f); + super(name, isSearchable, hasDocValues, TextSearchInfo.SIMPLE_MATCH_ONLY, meta); + setIndexAnalyzer(Lucene.KEYWORD_ANALYZER); + setSearchAnalyzer(Lucene.KEYWORD_ANALYZER); } public KeywordFieldType(String name) { - this(name, true, true, Collections.emptyMap()); + this(name, true, Defaults.FIELD_TYPE, false, + Lucene.KEYWORD_ANALYZER, Lucene.KEYWORD_ANALYZER, null, Collections.emptyMap(), 1f); } protected KeywordFieldType(KeywordFieldType ref) { diff --git a/server/src/main/java/org/elasticsearch/index/mapper/MappedFieldType.java b/server/src/main/java/org/elasticsearch/index/mapper/MappedFieldType.java index a4932e4c44f..9c378da4df0 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/MappedFieldType.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/MappedFieldType.java @@ -63,11 +63,11 @@ public abstract class MappedFieldType { private final String name; private final boolean docValues; private final boolean isIndexed; + private final TextSearchInfo textSearchInfo; private float boost; private NamedAnalyzer indexAnalyzer; private NamedAnalyzer searchAnalyzer; private NamedAnalyzer searchQuoteAnalyzer; - protected boolean hasPositions; private SimilarityProvider similarity; private boolean eagerGlobalOrdinals; private Map meta; @@ -83,14 +83,15 @@ public abstract class MappedFieldType { this.similarity = ref.similarity(); this.eagerGlobalOrdinals = ref.eagerGlobalOrdinals; this.meta = ref.meta; - this.hasPositions = ref.hasPositions; + this.textSearchInfo = ref.textSearchInfo; } - public MappedFieldType(String name, boolean isIndexed, boolean hasDocValues, Map meta) { + public MappedFieldType(String name, boolean isIndexed, boolean hasDocValues, TextSearchInfo textSearchInfo, Map meta) { setBoost(1.0f); this.name = Objects.requireNonNull(name); this.isIndexed = isIndexed; this.docValues = hasDocValues; + this.textSearchInfo = Objects.requireNonNull(textSearchInfo); this.meta = meta; } @@ -151,10 +152,6 @@ public abstract class MappedFieldType { this.boost = boost; } - public boolean hasPositions() { - return hasPositions; - } - public boolean hasDocValues() { return docValues; } @@ -411,4 +408,16 @@ public abstract class MappedFieldType { public void updateMeta(Map meta) { this.meta = meta; } + + /** + * Returns information on how any text in this field is indexed + * + * Fields that do not support any text-based queries should return + * {@link TextSearchInfo#NONE}. Some fields (eg numeric) may support + * only simple match queries, and can return + * {@link TextSearchInfo#SIMPLE_MATCH_ONLY} + */ + public TextSearchInfo getTextSearchInfo() { + return textSearchInfo; + } } diff --git a/server/src/main/java/org/elasticsearch/index/mapper/MapperService.java b/server/src/main/java/org/elasticsearch/index/mapper/MapperService.java index 0cb7f641826..12cc65316ea 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/MapperService.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/MapperService.java @@ -24,7 +24,6 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.message.ParameterizedMessage; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.DelegatingAnalyzerWrapper; -import org.apache.lucene.document.FieldType; import org.elasticsearch.Assertions; import org.elasticsearch.Version; import org.elasticsearch.cluster.metadata.IndexMetadata; @@ -198,20 +197,6 @@ public class MapperService extends AbstractIndexComponent implements Closeable { return this.documentParser; } - public FieldType getLuceneFieldType(String field) { - Mapper mapper = documentMapper().mappers().getMapper(field); - if (mapper == null) { - return null; - } - if (mapper instanceof FieldAliasMapper) { - return getLuceneFieldType(((FieldAliasMapper)mapper).path()); - } - if (mapper instanceof FieldMapper == false) { - return null; - } - return ((FieldMapper) mapper).fieldType; - } - /** * Parses the mappings (formatted as JSON) into a map */ diff --git a/server/src/main/java/org/elasticsearch/index/mapper/NumberFieldMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/NumberFieldMapper.java index b05062554df..94af1ce030f 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/NumberFieldMapper.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/NumberFieldMapper.java @@ -904,7 +904,7 @@ public class NumberFieldMapper extends FieldMapper { private final NumberType type; public NumberFieldType(String name, NumberType type, boolean isSearchable, boolean hasDocValues, Map meta) { - super(name, isSearchable, hasDocValues, meta); + super(name, isSearchable, hasDocValues, TextSearchInfo.SIMPLE_MATCH_ONLY, meta); this.type = Objects.requireNonNull(type); this.setIndexAnalyzer(Lucene.KEYWORD_ANALYZER); // allows number fields in significant text aggs - do we need this? this.setSearchAnalyzer(Lucene.KEYWORD_ANALYZER); // allows match queries on number fields diff --git a/server/src/main/java/org/elasticsearch/index/mapper/RangeFieldMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/RangeFieldMapper.java index f13436d6ca3..d529eaccd85 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/RangeFieldMapper.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/RangeFieldMapper.java @@ -193,7 +193,7 @@ public class RangeFieldMapper extends FieldMapper { protected final DateMathParser dateMathParser; public RangeFieldType(String name, RangeType type, boolean indexed, boolean hasDocValues, Map meta) { - super(name, indexed, hasDocValues, meta); + super(name, indexed, hasDocValues, TextSearchInfo.SIMPLE_MATCH_ONLY, meta); assert type != RangeType.DATE; this.rangeType = Objects.requireNonNull(type); dateTimeFormatter = null; @@ -207,7 +207,7 @@ public class RangeFieldMapper extends FieldMapper { } public RangeFieldType(String name, boolean indexed, boolean hasDocValues, DateFormatter formatter, Map meta) { - super(name, indexed, hasDocValues, meta); + super(name, indexed, hasDocValues, TextSearchInfo.SIMPLE_MATCH_ONLY, meta); this.rangeType = RangeType.DATE; this.dateTimeFormatter = Objects.requireNonNull(formatter); this.dateMathParser = dateTimeFormatter.toDateMathParser(); diff --git a/server/src/main/java/org/elasticsearch/index/mapper/RoutingFieldMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/RoutingFieldMapper.java index b2337de1539..9416f80b734 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/RoutingFieldMapper.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/RoutingFieldMapper.java @@ -110,7 +110,7 @@ public class RoutingFieldMapper extends MetadataFieldMapper { static RoutingFieldType INSTANCE = new RoutingFieldType(); private RoutingFieldType() { - super(NAME, true, false, Collections.emptyMap()); + super(NAME, true, false, TextSearchInfo.SIMPLE_MATCH_ONLY, Collections.emptyMap()); setIndexAnalyzer(Lucene.KEYWORD_ANALYZER); setSearchAnalyzer(Lucene.KEYWORD_ANALYZER); } diff --git a/server/src/main/java/org/elasticsearch/index/mapper/SeqNoFieldMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/SeqNoFieldMapper.java index 31a8800303c..66a0e581459 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/SeqNoFieldMapper.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/SeqNoFieldMapper.java @@ -122,7 +122,7 @@ public class SeqNoFieldMapper extends MetadataFieldMapper { static final class SeqNoFieldType extends SimpleMappedFieldType { SeqNoFieldType() { - super(NAME, true, true, Collections.emptyMap()); + super(NAME, true, true, TextSearchInfo.SIMPLE_MATCH_ONLY, Collections.emptyMap()); } protected SeqNoFieldType(SeqNoFieldType ref) { diff --git a/server/src/main/java/org/elasticsearch/index/mapper/SimpleMappedFieldType.java b/server/src/main/java/org/elasticsearch/index/mapper/SimpleMappedFieldType.java index cc011f4473c..8253bd599bd 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/SimpleMappedFieldType.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/SimpleMappedFieldType.java @@ -32,8 +32,9 @@ import java.util.Map; */ public abstract class SimpleMappedFieldType extends MappedFieldType { - protected SimpleMappedFieldType(String name, boolean isSearchable, boolean hasDocValues, Map meta) { - super(name, isSearchable, hasDocValues, meta); + protected SimpleMappedFieldType(String name, boolean isSearchable, boolean hasDocValues, + TextSearchInfo textSearchInfo, Map meta) { + super(name, isSearchable, hasDocValues, textSearchInfo, meta); } protected SimpleMappedFieldType(MappedFieldType ref) { diff --git a/server/src/main/java/org/elasticsearch/index/mapper/SourceFieldMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/SourceFieldMapper.java index 1dbafeca256..e9bdccab3f7 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/SourceFieldMapper.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/SourceFieldMapper.java @@ -149,7 +149,7 @@ public class SourceFieldMapper extends MetadataFieldMapper { public static final SourceFieldType INSTANCE = new SourceFieldType(); private SourceFieldType() { - super(NAME, false, false, Collections.emptyMap()); + super(NAME, false, false, TextSearchInfo.NONE, Collections.emptyMap()); } protected SourceFieldType(SourceFieldType ref) { diff --git a/server/src/main/java/org/elasticsearch/index/mapper/StringFieldType.java b/server/src/main/java/org/elasticsearch/index/mapper/StringFieldType.java index dac05567f92..a3b41bef7e3 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/StringFieldType.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/StringFieldType.java @@ -50,8 +50,9 @@ public abstract class StringFieldType extends TermBasedFieldType { private static final Pattern WILDCARD_PATTERN = Pattern.compile("(\\\\.)|([?*]+)"); - public StringFieldType(String name, boolean isSearchable, boolean hasDocValues, Map meta) { - super(name, isSearchable, hasDocValues, meta); + public StringFieldType(String name, boolean isSearchable, boolean hasDocValues, + TextSearchInfo textSearchInfo, Map meta) { + super(name, isSearchable, hasDocValues, textSearchInfo, meta); } protected StringFieldType(MappedFieldType ref) { diff --git a/server/src/main/java/org/elasticsearch/index/mapper/TermBasedFieldType.java b/server/src/main/java/org/elasticsearch/index/mapper/TermBasedFieldType.java index 078a17e3657..5d6db99baf9 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/TermBasedFieldType.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/TermBasedFieldType.java @@ -35,8 +35,8 @@ import java.util.Map; * with the inverted index. */ abstract class TermBasedFieldType extends SimpleMappedFieldType { - TermBasedFieldType(String name, boolean isSearchable, boolean hasDocValues, Map meta) { - super(name, isSearchable, hasDocValues, meta); + TermBasedFieldType(String name, boolean isSearchable, boolean hasDocValues, TextSearchInfo textSearchInfo, Map meta) { + super(name, isSearchable, hasDocValues, textSearchInfo, meta); } protected TermBasedFieldType(MappedFieldType ref) { diff --git a/server/src/main/java/org/elasticsearch/index/mapper/TextFieldMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/TextFieldMapper.java index 9eb47764da6..2047db42848 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/TextFieldMapper.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/TextFieldMapper.java @@ -187,8 +187,7 @@ public class TextFieldMapper extends FieldMapper { } private TextFieldType buildFieldType(BuilderContext context) { - TextFieldType ft = new TextFieldType(buildFullName(context), indexed, - fieldType.indexOptions().compareTo(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS) >= 0, meta); + TextFieldType ft = new TextFieldType(buildFullName(context), fieldType, meta); ft.setIndexAnalyzer(indexAnalyzer); ft.setSearchAnalyzer(searchAnalyzer); ft.setSearchQuoteAnalyzer(searchQuoteAnalyzer); @@ -203,7 +202,7 @@ public class TextFieldMapper extends FieldMapper { return ft; } - private PrefixFieldMapper buildPrefixMapper(BuilderContext context) { + private PrefixFieldMapper buildPrefixMapper(BuilderContext context, TextFieldType tft) { if (minPrefixChars == -1) { return null; } @@ -231,7 +230,7 @@ public class TextFieldMapper extends FieldMapper { if (fieldType.storeTermVectorOffsets()) { pft.setStoreTermVectorOffsets(true); } - PrefixFieldType prefixFieldType = new PrefixFieldType(fullName, fullName + "._index_prefix", + PrefixFieldType prefixFieldType = new PrefixFieldType(tft, fullName + "._index_prefix", minPrefixChars, maxPrefixChars, pft.indexOptions().compareTo(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS) >= 0); prefixFieldType.setAnalyzer(indexAnalyzer); return new PrefixFieldMapper(pft, prefixFieldType); @@ -264,7 +263,7 @@ public class TextFieldMapper extends FieldMapper { } TextFieldType tft = buildFieldType(context); return new TextFieldMapper(name, - fieldType, tft, positionIncrementGap, buildPrefixMapper(context), buildPhraseMapper(context, tft), + fieldType, tft, positionIncrementGap, buildPrefixMapper(context, tft), buildPhraseMapper(context, tft), multiFieldsBuilder.build(this, context), copyTo); } } @@ -367,7 +366,7 @@ public class TextFieldMapper extends FieldMapper { final TextFieldType parent; PhraseFieldType(TextFieldType parent) { - super(parent.name() + FAST_PHRASE_SUFFIX, true, false, Collections.emptyMap()); + super(parent.name() + FAST_PHRASE_SUFFIX, true, false, parent.getTextSearchInfo(), Collections.emptyMap()); setAnalyzer(parent.indexAnalyzer().name(), parent.indexAnalyzer().analyzer()); this.parent = parent; } @@ -396,10 +395,11 @@ public class TextFieldMapper extends FieldMapper { final int minChars; final int maxChars; - final String parentField; + final TextFieldType parentField; + final boolean hasPositions; - PrefixFieldType(String parentField, String name, int minChars, int maxChars, boolean hasPositions) { - super(name, true, false, Collections.emptyMap()); + PrefixFieldType(TextFieldType parentField, String name, int minChars, int maxChars, boolean hasPositions) { + super(name, true, false, parentField.getTextSearchInfo(), Collections.emptyMap()); this.minChars = minChars; this.maxChars = maxChars; this.parentField = parentField; @@ -437,7 +437,7 @@ public class TextFieldMapper extends FieldMapper { query.setRewriteMethod(method); return new BooleanQuery.Builder() .add(query, BooleanClause.Occur.SHOULD) - .add(new TermQuery(new Term(parentField, value)), BooleanClause.Occur.SHOULD) + .add(new TermQuery(new Term(parentField.name(), value)), BooleanClause.Occur.SHOULD) .build(); } @@ -556,18 +556,26 @@ public class TextFieldMapper extends FieldMapper { private int fielddataMinSegmentSize; private PrefixFieldType prefixFieldType; private boolean indexPhrases = false; + private final FieldType indexedFieldType; - public TextFieldType(String name, boolean indexed, boolean hasPositions, Map meta) { - super(name, indexed, false, meta); - this.hasPositions = hasPositions; + public TextFieldType(String name, FieldType indexedFieldType, Map meta) { + super(name, indexedFieldType.indexOptions() != IndexOptions.NONE, false, + new TextSearchInfo(indexedFieldType), meta); + this.indexedFieldType = indexedFieldType; fielddata = false; fielddataMinFrequency = Defaults.FIELDDATA_MIN_FREQUENCY; fielddataMaxFrequency = Defaults.FIELDDATA_MAX_FREQUENCY; fielddataMinSegmentSize = Defaults.FIELDDATA_MIN_SEGMENT_SIZE; } + public TextFieldType(String name, boolean indexed, Map meta) { + super(name, indexed, false, new TextSearchInfo(Defaults.FIELD_TYPE), meta); + this.indexedFieldType = Defaults.FIELD_TYPE; + fielddata = false; + } + public TextFieldType(String name) { - this(name, true, true, Collections.emptyMap()); + this(name, Defaults.FIELD_TYPE, Collections.emptyMap()); } protected TextFieldType(TextFieldType ref) { @@ -580,7 +588,7 @@ public class TextFieldMapper extends FieldMapper { if (ref.prefixFieldType != null) { this.prefixFieldType = ref.prefixFieldType.clone(); } - this.hasPositions = ref.hasPositions; + this.indexedFieldType = ref.indexedFieldType; } @Override @@ -652,10 +660,6 @@ public class TextFieldMapper extends FieldMapper { return this.prefixFieldType; } - public boolean hasPositions() { - return this.hasPositions; - } - @Override public String typeName() { return CONTENT_TYPE; @@ -680,7 +684,7 @@ public class TextFieldMapper extends FieldMapper { if (prefixFieldType != null && value.length() >= prefixFieldType.minChars && value.length() <= prefixFieldType.maxChars - && prefixFieldType.hasPositions()) { + && prefixFieldType.getTextSearchInfo().hasPositions()) { return new FieldMaskingSpanQuery(new SpanTermQuery(new Term(prefixFieldType.name(), indexedValueForSearch(value))), name()); } else { @@ -693,7 +697,7 @@ public class TextFieldMapper extends FieldMapper { @Override public Query existsQuery(QueryShardContext context) { - if (context.getMapperService().getLuceneFieldType(name()).omitNorms()) { + if (indexedFieldType.omitNorms()) { return new TermQuery(new Term(FieldNamesFieldMapper.NAME, name())); } else { return new NormsFieldExistsQuery(name()); @@ -703,7 +707,7 @@ public class TextFieldMapper extends FieldMapper { @Override public IntervalsSource intervals(String text, int maxGaps, boolean ordered, NamedAnalyzer analyzer, boolean prefix) throws IOException { - if (hasPositions() == false) { + if (getTextSearchInfo().hasPositions() == false) { throw new IllegalArgumentException("Cannot create intervals over field [" + name() + "] with no positions indexed"); } if (analyzer == null) { diff --git a/server/src/main/java/org/elasticsearch/index/mapper/TextSearchInfo.java b/server/src/main/java/org/elasticsearch/index/mapper/TextSearchInfo.java new file mode 100644 index 00000000000..618226f7cdf --- /dev/null +++ b/server/src/main/java/org/elasticsearch/index/mapper/TextSearchInfo.java @@ -0,0 +1,114 @@ +/* + * 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; + +import org.apache.lucene.document.FieldType; +import org.apache.lucene.index.IndexOptions; + +/** + * Encapsulates information about how to perform text searches over a field + */ +public class TextSearchInfo { + + private static final FieldType SIMPLE_MATCH_ONLY_FIELD_TYPE = new FieldType(); + static { + SIMPLE_MATCH_ONLY_FIELD_TYPE.setTokenized(false); + SIMPLE_MATCH_ONLY_FIELD_TYPE.setOmitNorms(true); + SIMPLE_MATCH_ONLY_FIELD_TYPE.freeze(); + } + + /** + * Defines indexing information for fields that support only simple match text queries + * + * Note that the results of {@link #isStored()} for this may not be accurate + */ + public static final TextSearchInfo SIMPLE_MATCH_ONLY = new TextSearchInfo(SIMPLE_MATCH_ONLY_FIELD_TYPE); + + /** + * Specifies that this field does not support text searching of any kind + */ + public static final TextSearchInfo NONE = new TextSearchInfo(SIMPLE_MATCH_ONLY_FIELD_TYPE); + + private final FieldType luceneFieldType; + + /** + * Create a TextSearchInfo by wrapping a lucene FieldType + */ + public TextSearchInfo(FieldType luceneFieldType) { + this.luceneFieldType = luceneFieldType; + } + + /** + * @return whether or not this field supports positional queries + */ + public boolean hasPositions() { + return luceneFieldType.indexOptions().compareTo(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS) >= 0; + } + + /** + * @return whether or not this field has indexed offsets for highlighting + */ + public boolean hasOffsets() { + return luceneFieldType.indexOptions().compareTo(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS) >= 0; + } + + /** + * @return whether or not this field has indexed norms + */ + public boolean hasNorms() { + return luceneFieldType.omitNorms() == false; + } + + /** + * @return whether or not this field is tokenized + */ + public boolean isTokenized() { + return luceneFieldType.tokenized(); + } + + /** + * @return whether or not this field is stored + */ + public boolean isStored() { + return luceneFieldType.stored(); // TODO move this directly to MappedFieldType? It's not text specific... + } + + /** + * What sort of term vectors are available + */ + public enum TermVector { NONE, DOCS, POSITIONS, OFFSETS } + + /** + * @return the type of term vectors available for this field + */ + public TermVector termVectors() { + if (luceneFieldType.storeTermVectors() == false) { + return TermVector.NONE; + } + if (luceneFieldType.storeTermVectorOffsets()) { + return TermVector.OFFSETS; + } + if (luceneFieldType.storeTermVectorPositions()) { + return TermVector.POSITIONS; + } + return TermVector.DOCS; + } + +} diff --git a/server/src/main/java/org/elasticsearch/index/mapper/TypeFieldMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/TypeFieldMapper.java index 2d6db2b249f..3ee32be7b34 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/TypeFieldMapper.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/TypeFieldMapper.java @@ -101,7 +101,7 @@ public class TypeFieldMapper extends MetadataFieldMapper { public static final TypeFieldType INSTANCE = new TypeFieldType(); private TypeFieldType() { - super(NAME, true, false, Collections.emptyMap()); + super(NAME, true, false, TextSearchInfo.SIMPLE_MATCH_ONLY, Collections.emptyMap()); } protected TypeFieldType(TypeFieldType ref) { diff --git a/server/src/main/java/org/elasticsearch/index/mapper/VersionFieldMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/VersionFieldMapper.java index d796217c5b9..56f7619569b 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/VersionFieldMapper.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/VersionFieldMapper.java @@ -72,7 +72,7 @@ public class VersionFieldMapper extends MetadataFieldMapper { public static final VersionFieldType INSTANCE = new VersionFieldType(); private VersionFieldType() { - super(NAME, false, true, Collections.emptyMap()); + super(NAME, false, true, TextSearchInfo.SIMPLE_MATCH_ONLY, Collections.emptyMap()); } protected VersionFieldType(VersionFieldType ref) { diff --git a/server/src/main/java/org/elasticsearch/index/query/IntervalsSourceProvider.java b/server/src/main/java/org/elasticsearch/index/query/IntervalsSourceProvider.java index ee4c6713947..c2e31b98669 100644 --- a/server/src/main/java/org/elasticsearch/index/query/IntervalsSourceProvider.java +++ b/server/src/main/java/org/elasticsearch/index/query/IntervalsSourceProvider.java @@ -663,7 +663,7 @@ public abstract class IntervalsSourceProvider implements NamedWriteable, ToXCont } private void checkPositions(MappedFieldType type) { - if (type.hasPositions() == false) { + if (type.getTextSearchInfo().hasPositions() == false) { throw new IllegalArgumentException("Cannot create intervals over field [" + type.name() + "] with no positions indexed"); } } @@ -801,7 +801,7 @@ public abstract class IntervalsSourceProvider implements NamedWriteable, ToXCont } private void checkPositions(MappedFieldType type) { - if (type.hasPositions() == false) { + if (type.getTextSearchInfo().hasPositions() == false) { throw new IllegalArgumentException("Cannot create intervals over field [" + type.name() + "] with no positions indexed"); } } diff --git a/server/src/main/java/org/elasticsearch/index/search/MatchQuery.java b/server/src/main/java/org/elasticsearch/index/search/MatchQuery.java index ed5a94235b3..3221ed51690 100644 --- a/server/src/main/java/org/elasticsearch/index/search/MatchQuery.java +++ b/server/src/main/java/org/elasticsearch/index/search/MatchQuery.java @@ -368,7 +368,7 @@ public class MatchQuery { super(analyzer); this.fieldType = fieldType; setEnablePositionIncrements(enablePositionIncrements); - if (fieldType.hasPositions()) { + if (fieldType.getTextSearchInfo().hasPositions()) { setAutoGenerateMultiTermSynonymsPhraseQuery(autoGenerateSynonymsPhraseQuery); } else { setAutoGenerateMultiTermSynonymsPhraseQuery(false); @@ -840,7 +840,7 @@ public class MatchQuery { } private void checkForPositions(String field) { - if (fieldType.hasPositions() == false) { + if (fieldType.getTextSearchInfo().hasPositions() == false) { throw new IllegalStateException("field:[" + field + "] was indexed without position data; cannot run PhraseQuery"); } } diff --git a/server/src/main/java/org/elasticsearch/index/search/QueryStringQueryParser.java b/server/src/main/java/org/elasticsearch/index/search/QueryStringQueryParser.java index ef38ecbcff3..35133f31a19 100644 --- a/server/src/main/java/org/elasticsearch/index/search/QueryStringQueryParser.java +++ b/server/src/main/java/org/elasticsearch/index/search/QueryStringQueryParser.java @@ -23,7 +23,6 @@ import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.TokenStream; import org.apache.lucene.analysis.tokenattributes.CharTermAttribute; import org.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute; -import org.apache.lucene.document.FieldType; import org.apache.lucene.index.Term; import org.apache.lucene.queryparser.classic.ParseException; import org.apache.lucene.queryparser.classic.Token; @@ -53,6 +52,7 @@ import org.elasticsearch.index.mapper.DateFieldMapper.DateFieldType; import org.elasticsearch.index.mapper.FieldNamesFieldMapper; import org.elasticsearch.index.mapper.MappedFieldType; import org.elasticsearch.index.mapper.MapperService; +import org.elasticsearch.index.mapper.TextSearchInfo; import org.elasticsearch.index.query.ExistsQueryBuilder; import org.elasticsearch.index.query.MultiMatchQueryBuilder; import org.elasticsearch.index.query.QueryShardContext; @@ -518,13 +518,12 @@ public class QueryStringQueryParser extends XQueryParser { Analyzer oldAnalyzer = getAnalyzer(); try { MappedFieldType currentFieldType = context.fieldMapper(field); - if (currentFieldType == null) { + if (currentFieldType == null || currentFieldType.getTextSearchInfo() == TextSearchInfo.NONE) { return newUnmappedFieldQuery(field); } setAnalyzer(forceAnalyzer == null ? queryBuilder.context.getSearchAnalyzer(currentFieldType) : forceAnalyzer); - FieldType ft = context.getMapperService().getLuceneFieldType(field); Query query = null; - if (ft.tokenized() == false) { + if (currentFieldType.getTextSearchInfo().isTokenized() == false) { query = currentFieldType.prefixQuery(termStr, getMultiTermRewriteMethod(), context); } else { query = getPossiblyAnalyzedPrefixQuery(currentFieldType.name(), termStr, currentFieldType); diff --git a/server/src/main/java/org/elasticsearch/index/termvectors/TermVectorsService.java b/server/src/main/java/org/elasticsearch/index/termvectors/TermVectorsService.java index aa1ca8304bf..e229b9c9ed1 100644 --- a/server/src/main/java/org/elasticsearch/index/termvectors/TermVectorsService.java +++ b/server/src/main/java/org/elasticsearch/index/termvectors/TermVectorsService.java @@ -51,6 +51,7 @@ import org.elasticsearch.index.mapper.ParsedDocument; import org.elasticsearch.index.mapper.SourceFieldMapper; import org.elasticsearch.index.mapper.SourceToParse; import org.elasticsearch.index.mapper.StringFieldType; +import org.elasticsearch.index.mapper.TextSearchInfo; import org.elasticsearch.index.mapper.Uid; import org.elasticsearch.index.shard.IndexShard; import org.elasticsearch.search.dfs.AggregatedDfs; @@ -201,7 +202,7 @@ public class TermVectorsService { continue; } // already retrieved, only if the analyzer hasn't been overridden at the field - if (indexShard.mapperService().getLuceneFieldType(field).storeTermVectors() && + if (fieldType.getTextSearchInfo().termVectors() != TextSearchInfo.TermVector.NONE && (request.perFieldAnalyzer() == null || !request.perFieldAnalyzer().containsKey(field))) { continue; } diff --git a/server/src/main/java/org/elasticsearch/search/fetch/subphase/highlight/FastVectorHighlighter.java b/server/src/main/java/org/elasticsearch/search/fetch/subphase/highlight/FastVectorHighlighter.java index b9b151b000c..e05c2c59ffc 100644 --- a/server/src/main/java/org/elasticsearch/search/fetch/subphase/highlight/FastVectorHighlighter.java +++ b/server/src/main/java/org/elasticsearch/search/fetch/subphase/highlight/FastVectorHighlighter.java @@ -18,7 +18,6 @@ */ package org.elasticsearch.search.fetch.subphase.highlight; -import org.apache.lucene.document.FieldType; import org.apache.lucene.search.highlight.Encoder; import org.apache.lucene.search.vectorhighlight.BaseFragmentsBuilder; import org.apache.lucene.search.vectorhighlight.BoundaryScanner; @@ -39,6 +38,7 @@ import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.text.Text; import org.elasticsearch.common.util.CollectionUtils; import org.elasticsearch.index.mapper.MappedFieldType; +import org.elasticsearch.index.mapper.TextSearchInfo; import org.elasticsearch.index.query.QueryShardContext; import org.elasticsearch.search.fetch.FetchPhaseExecutionException; import org.elasticsearch.search.fetch.FetchSubPhase; @@ -75,11 +75,12 @@ public class FastVectorHighlighter implements Highlighter { FetchSubPhase.HitContext hitContext = highlighterContext.hitContext; MappedFieldType fieldType = highlighterContext.fieldType; - if (canHighlight(highlighterContext.luceneFieldType) == false) { + if (canHighlight(fieldType) == false) { throw new IllegalArgumentException("the field [" + highlighterContext.fieldName + "] should be indexed with term vector with position offsets to be used with fast vector highlighter"); } + TextSearchInfo tsi = fieldType.getTextSearchInfo(); Encoder encoder = field.fieldOptions().encoder().equals("html") ? HighlightUtils.Encoders.HTML : HighlightUtils.Encoders.DEFAULT; @@ -99,7 +100,7 @@ public class FastVectorHighlighter implements Highlighter { if (field.fieldOptions().numberOfFragments() == 0) { fragListBuilder = new SingleFragListBuilder(); - if (!forceSource && highlighterContext.luceneFieldType.stored()) { + if (!forceSource && tsi.isStored()) { fragmentsBuilder = new SimpleFragmentsBuilder(fieldType, field.fieldOptions().preTags(), field.fieldOptions().postTags(), boundaryScanner); } else { @@ -110,7 +111,7 @@ public class FastVectorHighlighter implements Highlighter { fragListBuilder = field.fieldOptions().fragmentOffset() == -1 ? new SimpleFragListBuilder() : new SimpleFragListBuilder(field.fieldOptions().fragmentOffset()); if (field.fieldOptions().scoreOrdered()) { - if (!forceSource && highlighterContext.luceneFieldType.stored()) { + if (!forceSource && tsi.isStored()) { fragmentsBuilder = new ScoreOrderFragmentsBuilder(field.fieldOptions().preTags(), field.fieldOptions().postTags(), boundaryScanner); } else { @@ -118,7 +119,7 @@ public class FastVectorHighlighter implements Highlighter { field.fieldOptions().preTags(), field.fieldOptions().postTags(), boundaryScanner); } } else { - if (!forceSource && highlighterContext.luceneFieldType.stored()) { + if (!forceSource && tsi.isStored()) { fragmentsBuilder = new SimpleFragmentsBuilder(fieldType, field.fieldOptions().preTags(), field.fieldOptions().postTags(), boundaryScanner); } else { @@ -211,10 +212,8 @@ public class FastVectorHighlighter implements Highlighter { } @Override - public boolean canHighlight(FieldType fieldType) { - return fieldType.storeTermVectors() - && fieldType.storeTermVectorOffsets() - && fieldType.storeTermVectorPositions(); + public boolean canHighlight(MappedFieldType ft) { + return ft.getTextSearchInfo().termVectors() == TextSearchInfo.TermVector.OFFSETS; } private static BoundaryScanner getBoundaryScanner(Field field) { diff --git a/server/src/main/java/org/elasticsearch/search/fetch/subphase/highlight/HighlightPhase.java b/server/src/main/java/org/elasticsearch/search/fetch/subphase/highlight/HighlightPhase.java index f182d43316d..baf71a492d7 100644 --- a/server/src/main/java/org/elasticsearch/search/fetch/subphase/highlight/HighlightPhase.java +++ b/server/src/main/java/org/elasticsearch/search/fetch/subphase/highlight/HighlightPhase.java @@ -108,10 +108,9 @@ public class HighlightPhase implements FetchSubPhase { highlightQuery = query; } HighlighterContext highlighterContext = new HighlighterContext(fieldType.name(), - field, fieldType, shardTarget, context, highlight, hitContext, highlightQuery, - context.getMapperService().getLuceneFieldType(fieldType.name())); + field, fieldType, shardTarget, context, highlight, hitContext, highlightQuery); - if ((highlighter.canHighlight(highlighterContext.luceneFieldType) == false) && fieldNameContainsWildcards) { + if ((highlighter.canHighlight(fieldType) == false) && fieldNameContainsWildcards) { // if several fieldnames matched the wildcard then we want to skip those that we cannot highlight continue; } diff --git a/server/src/main/java/org/elasticsearch/search/fetch/subphase/highlight/HighlightUtils.java b/server/src/main/java/org/elasticsearch/search/fetch/subphase/highlight/HighlightUtils.java index f03d6b7650a..1bebf8026f9 100644 --- a/server/src/main/java/org/elasticsearch/search/fetch/subphase/highlight/HighlightUtils.java +++ b/server/src/main/java/org/elasticsearch/search/fetch/subphase/highlight/HighlightUtils.java @@ -18,12 +18,12 @@ */ package org.elasticsearch.search.fetch.subphase.highlight; -import org.apache.lucene.document.FieldType; import org.apache.lucene.search.highlight.DefaultEncoder; import org.apache.lucene.search.highlight.Encoder; import org.apache.lucene.search.highlight.SimpleHTMLEncoder; import org.elasticsearch.index.fieldvisitor.CustomFieldsVisitor; import org.elasticsearch.index.mapper.MappedFieldType; +import org.elasticsearch.index.mapper.TextSearchInfo; import org.elasticsearch.index.query.QueryShardContext; import org.elasticsearch.search.fetch.FetchSubPhase; import org.elasticsearch.search.lookup.SourceLookup; @@ -53,8 +53,8 @@ public final class HighlightUtils { boolean forceSource) throws IOException { //percolator needs to always load from source, thus it sets the global force source to true List textsToHighlight; - FieldType luceneFieldType = context.getMapperService().getLuceneFieldType(fieldType.name()); - if (forceSource == false && luceneFieldType.stored()) { + TextSearchInfo tsi = fieldType.getTextSearchInfo(); + if (forceSource == false && tsi.isStored()) { CustomFieldsVisitor fieldVisitor = new CustomFieldsVisitor(singleton(fieldType.name()), false); hitContext.reader().document(hitContext.docId(), fieldVisitor); textsToHighlight = fieldVisitor.fields().get(fieldType.name()); diff --git a/server/src/main/java/org/elasticsearch/search/fetch/subphase/highlight/Highlighter.java b/server/src/main/java/org/elasticsearch/search/fetch/subphase/highlight/Highlighter.java index a1028cc9d9a..7de8a9f9a9b 100644 --- a/server/src/main/java/org/elasticsearch/search/fetch/subphase/highlight/Highlighter.java +++ b/server/src/main/java/org/elasticsearch/search/fetch/subphase/highlight/Highlighter.java @@ -18,7 +18,7 @@ */ package org.elasticsearch.search.fetch.subphase.highlight; -import org.apache.lucene.document.FieldType; +import org.elasticsearch.index.mapper.MappedFieldType; /** * Highlights a search result. @@ -27,5 +27,5 @@ public interface Highlighter { HighlightField highlight(HighlighterContext highlighterContext); - boolean canHighlight(FieldType fieldType); + boolean canHighlight(MappedFieldType fieldType); } diff --git a/server/src/main/java/org/elasticsearch/search/fetch/subphase/highlight/HighlighterContext.java b/server/src/main/java/org/elasticsearch/search/fetch/subphase/highlight/HighlighterContext.java index 86d90bda8c5..aedb6b3999c 100644 --- a/server/src/main/java/org/elasticsearch/search/fetch/subphase/highlight/HighlighterContext.java +++ b/server/src/main/java/org/elasticsearch/search/fetch/subphase/highlight/HighlighterContext.java @@ -18,7 +18,6 @@ */ package org.elasticsearch.search.fetch.subphase.highlight; -import org.apache.lucene.document.FieldType; import org.apache.lucene.search.Query; import org.elasticsearch.index.mapper.MappedFieldType; import org.elasticsearch.index.query.QueryShardContext; @@ -35,7 +34,6 @@ public class HighlighterContext { public final SearchContextHighlight highlight; public final FetchSubPhase.HitContext hitContext; public final Query query; - public final FieldType luceneFieldType; public HighlighterContext(String fieldName, SearchContextHighlight.Field field, @@ -44,7 +42,7 @@ public class HighlighterContext { QueryShardContext context, SearchContextHighlight highlight, FetchSubPhase.HitContext hitContext, - Query query, FieldType luceneFieldType) { + Query query) { this.fieldName = fieldName; this.field = field; this.fieldType = fieldType; @@ -53,6 +51,5 @@ public class HighlighterContext { this.highlight = highlight; this.hitContext = hitContext; this.query = query; - this.luceneFieldType = luceneFieldType; } } diff --git a/server/src/main/java/org/elasticsearch/search/fetch/subphase/highlight/PlainHighlighter.java b/server/src/main/java/org/elasticsearch/search/fetch/subphase/highlight/PlainHighlighter.java index 12f7d0d5fa6..a12a4cbecab 100644 --- a/server/src/main/java/org/elasticsearch/search/fetch/subphase/highlight/PlainHighlighter.java +++ b/server/src/main/java/org/elasticsearch/search/fetch/subphase/highlight/PlainHighlighter.java @@ -22,7 +22,6 @@ import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.TokenStream; import org.apache.lucene.analysis.tokenattributes.CharTermAttribute; import org.apache.lucene.analysis.tokenattributes.OffsetAttribute; -import org.apache.lucene.document.FieldType; import org.apache.lucene.search.highlight.Encoder; import org.apache.lucene.search.highlight.Formatter; import org.apache.lucene.search.highlight.Fragmenter; @@ -203,7 +202,7 @@ public class PlainHighlighter implements Highlighter { } @Override - public boolean canHighlight(FieldType fieldType) { + public boolean canHighlight(MappedFieldType fieldType) { return true; } diff --git a/server/src/main/java/org/elasticsearch/search/fetch/subphase/highlight/UnifiedHighlighter.java b/server/src/main/java/org/elasticsearch/search/fetch/subphase/highlight/UnifiedHighlighter.java index b7703789ac2..def9d16c594 100644 --- a/server/src/main/java/org/elasticsearch/search/fetch/subphase/highlight/UnifiedHighlighter.java +++ b/server/src/main/java/org/elasticsearch/search/fetch/subphase/highlight/UnifiedHighlighter.java @@ -19,9 +19,6 @@ package org.elasticsearch.search.fetch.subphase.highlight; import org.apache.lucene.analysis.Analyzer; -import org.apache.lucene.document.FieldType; -import org.apache.lucene.index.FieldInfo; -import org.apache.lucene.index.IndexOptions; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.highlight.Encoder; import org.apache.lucene.search.uhighlight.BoundedBreakIteratorScanner; @@ -40,6 +37,7 @@ import org.elasticsearch.index.mapper.DocumentMapper; import org.elasticsearch.index.mapper.IdFieldMapper; import org.elasticsearch.index.mapper.KeywordFieldMapper; import org.elasticsearch.index.mapper.MappedFieldType; +import org.elasticsearch.index.mapper.TextSearchInfo; import org.elasticsearch.index.query.QueryShardContext; import org.elasticsearch.search.fetch.FetchPhaseExecutionException; import org.elasticsearch.search.fetch.FetchSubPhase; @@ -56,7 +54,7 @@ import static org.apache.lucene.search.uhighlight.CustomUnifiedHighlighter.MULTI public class UnifiedHighlighter implements Highlighter { @Override - public boolean canHighlight(FieldType fieldType) { + public boolean canHighlight(MappedFieldType fieldType) { return true; } @@ -89,8 +87,7 @@ public class UnifiedHighlighter implements Highlighter { final IndexSearcher searcher = new IndexSearcher(hitContext.reader()); final CustomUnifiedHighlighter highlighter; final String fieldValue = mergeFieldValues(fieldValues, MULTIVAL_SEP_CHAR); - FieldInfo fi = hitContext.reader().getFieldInfos().fieldInfo(field.field()); - final OffsetSource offsetSource = getOffsetSource(highlighterContext.luceneFieldType); + final OffsetSource offsetSource = getOffsetSource(fieldType); int fieldValueLength = fieldValue.length(); if (keywordIgnoreAbove != null && fieldValueLength > keywordIgnoreAbove) { return null; // skip highlighting keyword terms that were ignored during indexing @@ -105,7 +102,7 @@ public class UnifiedHighlighter implements Highlighter { } if (numberOfFragments == 0 // non-tokenized fields should not use any break iterator (ignore boundaryScannerType) - || highlighterContext.luceneFieldType.tokenized() == false) { + || fieldType.getTextSearchInfo().isTokenized() == false) { // we use a control char to separate values, which is the only char that the custom break iterator // breaks the text on, so we don't lose the distinction between the different values of a field and we // get back a snippet per value @@ -220,11 +217,13 @@ public class UnifiedHighlighter implements Highlighter { return rawValue.substring(0, Math.min(rawValue.length(), Integer.MAX_VALUE - 1)); } - protected OffsetSource getOffsetSource(FieldType fieldType) { - if (fieldType.indexOptions() == IndexOptions.DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS) { - return fieldType.storeTermVectors() ? OffsetSource.POSTINGS_WITH_TERM_VECTORS : OffsetSource.POSTINGS; + protected OffsetSource getOffsetSource(MappedFieldType fieldType) { + TextSearchInfo tsi = fieldType.getTextSearchInfo(); + if (tsi.hasOffsets()) { + return tsi.termVectors() != TextSearchInfo.TermVector.NONE + ? OffsetSource.POSTINGS_WITH_TERM_VECTORS : OffsetSource.POSTINGS; } - if (fieldType.storeTermVectorOffsets()) { + if (tsi.termVectors() == TextSearchInfo.TermVector.OFFSETS) { return OffsetSource.TERM_VECTORS; } return OffsetSource.ANALYSIS; diff --git a/server/src/test/java/org/elasticsearch/index/mapper/DateFieldMapperTests.java b/server/src/test/java/org/elasticsearch/index/mapper/DateFieldMapperTests.java index cb7c41f91a3..4dde9da41b0 100644 --- a/server/src/test/java/org/elasticsearch/index/mapper/DateFieldMapperTests.java +++ b/server/src/test/java/org/elasticsearch/index/mapper/DateFieldMapperTests.java @@ -390,7 +390,8 @@ public class DateFieldMapperTests extends FieldMapperTestCase { @Override protected TextFieldType createDefaultFieldType(String name, Map meta) { - return new TextFieldType(name, true, true, meta); + return new TextFieldType(name, true, meta); } public void testTermQuery() { MappedFieldType ft = new TextFieldType("field"); assertEquals(new TermQuery(new Term("field", "foo")), ft.termQuery("foo", null)); - MappedFieldType unsearchable = new TextFieldType("field", false, true, Collections.emptyMap()); + MappedFieldType unsearchable = new TextFieldType("field", false, Collections.emptyMap()); IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> unsearchable.termQuery("bar", null)); assertEquals("Cannot search on field [field] since it is not indexed.", e.getMessage()); @@ -98,7 +98,7 @@ public class TextFieldTypeTests extends FieldTypeTestCase { assertEquals(new TermInSetQuery("field", terms), ft.termsQuery(Arrays.asList("foo", "bar"), null)); - MappedFieldType unsearchable = new TextFieldType("field", false, true, Collections.emptyMap()); + MappedFieldType unsearchable = new TextFieldType("field", false, Collections.emptyMap()); IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> unsearchable.termsQuery(Arrays.asList("foo", "bar"), null)); assertEquals("Cannot search on field [field] since it is not indexed.", e.getMessage()); @@ -120,7 +120,7 @@ public class TextFieldTypeTests extends FieldTypeTestCase { assertEquals(new RegexpQuery(new Term("field","foo.*")), ft.regexpQuery("foo.*", 0, 10, null, MOCK_QSC)); - MappedFieldType unsearchable = new TextFieldType("field", false, true, Collections.emptyMap()); + MappedFieldType unsearchable = new TextFieldType("field", false, Collections.emptyMap()); IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> unsearchable.regexpQuery("foo.*", 0, 10, null, MOCK_QSC)); assertEquals("Cannot search on field [field] since it is not indexed.", e.getMessage()); @@ -136,7 +136,7 @@ public class TextFieldTypeTests extends FieldTypeTestCase { assertEquals(new FuzzyQuery(new Term("field","foo"), 2, 1, 50, true), ft.fuzzyQuery("foo", Fuzziness.fromEdits(2), 1, 50, true, MOCK_QSC)); - MappedFieldType unsearchable = new TextFieldType("field", false, true, Collections.emptyMap()); + MappedFieldType unsearchable = new TextFieldType("field", false, Collections.emptyMap()); IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> unsearchable.fuzzyQuery("foo", Fuzziness.fromEdits(2), 1, 50, true, MOCK_QSC)); assertEquals("Cannot search on field [field] since it is not indexed.", e.getMessage()); @@ -150,7 +150,7 @@ public class TextFieldTypeTests extends FieldTypeTestCase { public void testIndexPrefixes() { TextFieldType ft = new TextFieldType("field"); - ft.setPrefixFieldType(new TextFieldMapper.PrefixFieldType("field", "field._index_prefix", 2, 10, true)); + ft.setPrefixFieldType(new TextFieldMapper.PrefixFieldType(ft, "field._index_prefix", 2, 10, true)); Query q = ft.prefixQuery("goin", CONSTANT_SCORE_REWRITE, randomMockShardContext()); assertEquals(new ConstantScoreQuery(new TermQuery(new Term("field._index_prefix", "goin"))), q); diff --git a/server/src/test/java/org/elasticsearch/index/query/ExistsQueryBuilderTests.java b/server/src/test/java/org/elasticsearch/index/query/ExistsQueryBuilderTests.java index 417b73d9de4..d4402843b7d 100644 --- a/server/src/test/java/org/elasticsearch/index/query/ExistsQueryBuilderTests.java +++ b/server/src/test/java/org/elasticsearch/index/query/ExistsQueryBuilderTests.java @@ -104,7 +104,7 @@ public class ExistsQueryBuilderTests extends AbstractQueryTestCase meta) { - super(name, false, hasDocValues, meta); + super(name, false, hasDocValues, TextSearchInfo.SIMPLE_MATCH_ONLY, meta); } HistogramFieldType(HistogramFieldType ref) { diff --git a/x-pack/plugin/mapper-flattened/src/main/java/org/elasticsearch/xpack/flattened/mapper/FlatObjectFieldMapper.java b/x-pack/plugin/mapper-flattened/src/main/java/org/elasticsearch/xpack/flattened/mapper/FlatObjectFieldMapper.java index 3213ddb65ee..c45dd2b7015 100644 --- a/x-pack/plugin/mapper-flattened/src/main/java/org/elasticsearch/xpack/flattened/mapper/FlatObjectFieldMapper.java +++ b/x-pack/plugin/mapper-flattened/src/main/java/org/elasticsearch/xpack/flattened/mapper/FlatObjectFieldMapper.java @@ -47,6 +47,7 @@ import org.elasticsearch.index.mapper.MapperParsingException; import org.elasticsearch.index.mapper.MapperService; import org.elasticsearch.index.mapper.ParseContext; import org.elasticsearch.index.mapper.StringFieldType; +import org.elasticsearch.index.mapper.TextSearchInfo; import org.elasticsearch.index.query.QueryShardContext; import org.elasticsearch.indices.breaker.CircuitBreakerService; import org.elasticsearch.search.DocValueFormat; @@ -231,7 +232,7 @@ public final class FlatObjectFieldMapper extends DynamicKeyFieldMapper { public KeyedFlatObjectFieldType(String name, boolean indexed, boolean hasDocValues, String key, boolean splitQueriesOnWhitespace, Map meta) { - super(name, indexed, hasDocValues, meta); + super(name, indexed, hasDocValues, TextSearchInfo.SIMPLE_MATCH_ONLY, meta); setIndexAnalyzer(Lucene.KEYWORD_ANALYZER); if (splitQueriesOnWhitespace == false) { setSearchAnalyzer(Lucene.KEYWORD_ANALYZER); @@ -482,7 +483,7 @@ public final class FlatObjectFieldMapper extends DynamicKeyFieldMapper { public RootFlatObjectFieldType(String name, boolean indexed, boolean hasDocValues, Map meta, boolean splitQueriesOnWhitespace) { - super(name, indexed, hasDocValues, meta); + super(name, indexed, hasDocValues, TextSearchInfo.SIMPLE_MATCH_ONLY, meta); this.splitQueriesOnWhitespace = splitQueriesOnWhitespace; setIndexAnalyzer(Lucene.KEYWORD_ANALYZER); if (splitQueriesOnWhitespace) { diff --git a/x-pack/plugin/vectors/src/main/java/org/elasticsearch/xpack/vectors/mapper/DenseVectorFieldMapper.java b/x-pack/plugin/vectors/src/main/java/org/elasticsearch/xpack/vectors/mapper/DenseVectorFieldMapper.java index 01faf432e7c..2e1140afa24 100644 --- a/x-pack/plugin/vectors/src/main/java/org/elasticsearch/xpack/vectors/mapper/DenseVectorFieldMapper.java +++ b/x-pack/plugin/vectors/src/main/java/org/elasticsearch/xpack/vectors/mapper/DenseVectorFieldMapper.java @@ -24,6 +24,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.TextSearchInfo; import org.elasticsearch.index.query.QueryShardContext; import org.elasticsearch.search.DocValueFormat; import org.elasticsearch.search.aggregations.support.CoreValuesSourceType; @@ -99,7 +100,7 @@ public class DenseVectorFieldMapper extends FieldMapper { private final int dims; public DenseVectorFieldType(String name, int dims, Map meta) { - super(name, false, false, meta); + super(name, false, false, TextSearchInfo.NONE, meta); this.dims = dims; } diff --git a/x-pack/plugin/vectors/src/main/java/org/elasticsearch/xpack/vectors/mapper/SparseVectorFieldMapper.java b/x-pack/plugin/vectors/src/main/java/org/elasticsearch/xpack/vectors/mapper/SparseVectorFieldMapper.java index 8062d039b04..361fb9d19ec 100644 --- a/x-pack/plugin/vectors/src/main/java/org/elasticsearch/xpack/vectors/mapper/SparseVectorFieldMapper.java +++ b/x-pack/plugin/vectors/src/main/java/org/elasticsearch/xpack/vectors/mapper/SparseVectorFieldMapper.java @@ -24,6 +24,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.TextSearchInfo; import org.elasticsearch.index.query.QueryShardContext; import org.elasticsearch.search.DocValueFormat; import org.elasticsearch.search.aggregations.support.CoreValuesSourceType; @@ -86,7 +87,7 @@ public class SparseVectorFieldMapper extends FieldMapper { public static final class SparseVectorFieldType extends MappedFieldType { public SparseVectorFieldType(String name, Map meta) { - super(name, false, false, meta); + super(name, false, false, TextSearchInfo.NONE, meta); } protected SparseVectorFieldType(SparseVectorFieldType ref) { diff --git a/x-pack/plugin/wildcard/src/main/java/org/elasticsearch/xpack/wildcard/mapper/WildcardFieldMapper.java b/x-pack/plugin/wildcard/src/main/java/org/elasticsearch/xpack/wildcard/mapper/WildcardFieldMapper.java index bdce3c02a50..c3a1f80ab20 100644 --- a/x-pack/plugin/wildcard/src/main/java/org/elasticsearch/xpack/wildcard/mapper/WildcardFieldMapper.java +++ b/x-pack/plugin/wildcard/src/main/java/org/elasticsearch/xpack/wildcard/mapper/WildcardFieldMapper.java @@ -61,6 +61,7 @@ import org.elasticsearch.index.mapper.MapperParsingException; import org.elasticsearch.index.mapper.MapperService; import org.elasticsearch.index.mapper.ParseContext; import org.elasticsearch.index.mapper.ParseContext.Document; +import org.elasticsearch.index.mapper.TextSearchInfo; import org.elasticsearch.index.query.QueryShardContext; import org.elasticsearch.index.similarity.SimilarityProvider; import org.elasticsearch.indices.breaker.CircuitBreakerService; @@ -175,7 +176,7 @@ public class WildcardFieldMapper extends FieldMapper { @Override public WildcardFieldMapper build(BuilderContext context) { return new WildcardFieldMapper( - name, fieldType, new WildcardFieldType(buildFullName(context), meta), ignoreAbove, + name, fieldType, new WildcardFieldType(buildFullName(context), fieldType, meta), ignoreAbove, multiFieldsBuilder.build(this, context), copyTo, nullValue); } } @@ -215,8 +216,8 @@ public class WildcardFieldMapper extends FieldMapper { static Analyzer lowercaseNormalizer = new LowercaseNormalizer(); - public WildcardFieldType(String name, Map meta) { - super(name, true, true, meta); + public WildcardFieldType(String name, FieldType fieldType, Map meta) { + super(name, true, true, new TextSearchInfo(fieldType), meta); setIndexAnalyzer(WILDCARD_ANALYZER); setSearchAnalyzer(Lucene.KEYWORD_ANALYZER); } diff --git a/x-pack/plugin/wildcard/src/test/java/org/elasticsearch/xpack/wildcard/mapper/WildcardFieldTypeTests.java b/x-pack/plugin/wildcard/src/test/java/org/elasticsearch/xpack/wildcard/mapper/WildcardFieldTypeTests.java index 37d6232e96c..8f2b5b00b15 100644 --- a/x-pack/plugin/wildcard/src/test/java/org/elasticsearch/xpack/wildcard/mapper/WildcardFieldTypeTests.java +++ b/x-pack/plugin/wildcard/src/test/java/org/elasticsearch/xpack/wildcard/mapper/WildcardFieldTypeTests.java @@ -16,6 +16,6 @@ public class WildcardFieldTypeTests extends FieldTypeTestCase { @Override protected MappedFieldType createDefaultFieldType(String name, Map meta) { - return new WildcardFieldMapper.WildcardFieldType(name, meta); + return new WildcardFieldMapper.WildcardFieldType(name, WildcardFieldMapper.Defaults.FIELD_TYPE, meta); } }