From 7405af8060bd32bf2ae7917a13c441e4214339b8 Mon Sep 17 00:00:00 2001 From: Alan Woodward Date: Tue, 6 Oct 2020 10:27:37 +0100 Subject: [PATCH] Convert TypeFieldType to a constant field type (#63214) In 6x and 7x, indexes can have only one type, which means that we can rework all queries against the type field to use a ConstantFieldType. This has already been done in master with the removal of the TypeFieldMapper, but we still need that class in 7x to deal with nested documents. This commit leaves TypeFieldMapper in place, but refactors TypeFieldType to extend ConstantFieldType and consolidates deprecation warnings within that class. It also incidentally removes the requirement to pass a MapperService to IndexFieldData.Builder#build, which should allow #63197 to be backported. --- .../index/mapper/DocumentMapper.java | 5 - .../index/mapper/MappedFieldType.java | 4 - .../index/mapper/MapperService.java | 5 + .../index/mapper/TypeFieldMapper.java | 228 ++++-------------- .../index/query/QueryShardContext.java | 8 - .../index/query/TypeQueryBuilder.java | 3 +- .../search/DefaultSearchContext.java | 9 +- .../search/lookup/LeafFieldsLookup.java | 1 + .../mapper/LegacyTypeFieldMapperTests.java | 1 + .../index/mapper/TypeFieldMapperTests.java | 1 + .../index/mapper/TypeFieldTypeTests.java | 50 +--- .../index/query/TermQueryBuilderTests.java | 6 +- .../index/query/TermsQueryBuilderTests.java | 3 +- .../index/query/TypeQueryBuilderTests.java | 11 +- .../query/WildcardQueryBuilderTests.java | 3 +- .../support/ValuesSourceConfigTests.java | 2 +- 16 files changed, 84 insertions(+), 256 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/index/mapper/DocumentMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/DocumentMapper.java index 7f007d8ab93..e62d743edd4 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/DocumentMapper.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/DocumentMapper.java @@ -40,7 +40,6 @@ import org.elasticsearch.index.IndexSettings; import org.elasticsearch.index.analysis.IndexAnalyzers; import org.elasticsearch.index.mapper.MapperService.MergeReason; import org.elasticsearch.index.mapper.MetadataFieldMapper.TypeParser; -import org.elasticsearch.index.query.QueryShardContext; import org.elasticsearch.search.internal.SearchContext; import java.io.IOException; @@ -208,10 +207,6 @@ public class DocumentMapper implements ToXContentFragment { return metadataMapper(IndexFieldMapper.class); } - public Query typeFilter(QueryShardContext context) { - return typeMapper().fieldType().termQuery(type, context); - } - public boolean hasNestedObjects() { return mappers().hasNested(); } 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 d7e3d753abc..bbde6516fbd 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/MappedFieldType.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/MappedFieldType.java @@ -377,10 +377,6 @@ public abstract class MappedFieldType { while (termQuery instanceof BoostQuery) { termQuery = ((BoostQuery) termQuery).getQuery(); } - if (termQuery instanceof TypeFieldMapper.TypesQuery) { - assert ((TypeFieldMapper.TypesQuery) termQuery).getTerms().length == 1; - return new Term(TypeFieldMapper.NAME, ((TypeFieldMapper.TypesQuery) termQuery).getTerms()[0]); - } if (termQuery instanceof TermInSetQuery) { TermInSetQuery tisQuery = (TermInSetQuery) termQuery; PrefixCodedTerms terms = tisQuery.getTermData(); 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 524a1776a3f..53853f1718c 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/MapperService.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/MapperService.java @@ -593,6 +593,11 @@ public class MapperService extends AbstractIndexComponent implements Closeable { * Given the full name of a field, returns its {@link MappedFieldType}. */ public MappedFieldType fieldType(String fullName) { + if (fullName.equals(TypeFieldMapper.NAME)) { + String type = mapper == null ? null : mapper.type(); + return new TypeFieldMapper.TypeFieldType(type); + } + return this.mapper == null ? null : this.mapper.fieldTypes().get(fullName); } 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 d9dadea3b38..af7b4f56ae7 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/TypeFieldMapper.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/TypeFieldMapper.java @@ -19,48 +19,40 @@ package org.elasticsearch.index.mapper; - import org.apache.lucene.document.Field; +import org.apache.lucene.document.Field; import org.apache.lucene.document.FieldType; import org.apache.lucene.document.SortedSetDocValuesField; import org.apache.lucene.index.IndexOptions; -import org.apache.lucene.index.IndexReader; -import org.apache.lucene.index.Term; -import org.apache.lucene.index.TermStates; -import org.apache.lucene.search.AutomatonQuery; -import org.apache.lucene.search.BooleanClause; -import org.apache.lucene.search.BooleanQuery; -import org.apache.lucene.search.ConstantScoreQuery; import org.apache.lucene.search.MatchAllDocsQuery; import org.apache.lucene.search.MatchNoDocsQuery; -import org.apache.lucene.search.MultiTermQuery; import org.apache.lucene.search.Query; -import org.apache.lucene.search.TermInSetQuery; -import org.apache.lucene.search.TermQuery; -import org.apache.lucene.search.WildcardQuery; import org.apache.lucene.util.BytesRef; -import org.elasticsearch.ElasticsearchException; -import org.elasticsearch.common.lucene.search.AutomatonQueries; -import org.elasticsearch.common.lucene.search.Queries; +import org.elasticsearch.common.geo.ShapeRelation; +import org.elasticsearch.common.logging.DeprecationLogger; +import org.elasticsearch.common.regex.Regex; +import org.elasticsearch.common.time.DateMathParser; import org.elasticsearch.index.fielddata.IndexFieldData; import org.elasticsearch.index.fielddata.plain.ConstantIndexFieldData; import org.elasticsearch.index.query.QueryShardContext; -import org.elasticsearch.index.query.support.QueryParsers; import org.elasticsearch.search.aggregations.support.CoreValuesSourceType; import org.elasticsearch.search.lookup.SearchLookup; -import java.io.IOException; -import java.util.Arrays; +import java.time.ZoneId; import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; import java.util.function.Function; import java.util.function.Supplier; -import static org.elasticsearch.search.SearchService.ALLOW_EXPENSIVE_QUERIES; - public class TypeFieldMapper extends MetadataFieldMapper { + private static final DeprecationLogger deprecationLogger = DeprecationLogger.getLogger(TypeFieldType.class); + + public static final String TYPES_DEPRECATION_MESSAGE = "[types removal] Using the _type field " + + "in queries and aggregations is deprecated, prefer to use a field instead."; + + public static void emitTypesDeprecationWarning() { + deprecationLogger.deprecate("query_with_types", TYPES_DEPRECATION_MESSAGE); + } + public static final String NAME = "_type"; public static final String CONTENT_TYPE = "_type"; @@ -80,12 +72,13 @@ public class TypeFieldMapper extends MetadataFieldMapper { } } - public static final class TypeFieldType extends StringFieldType { + public static final class TypeFieldType extends ConstantFieldType { - public static final TypeFieldType INSTANCE = new TypeFieldType(); + private final String type; - private TypeFieldType() { - super(NAME, true, false, false, TextSearchInfo.SIMPLE_MATCH_ONLY, Collections.emptyMap()); + public TypeFieldType(String type) { + super(NAME, Collections.emptyMap()); + this.type = type; } @Override @@ -95,6 +88,7 @@ public class TypeFieldMapper extends MetadataFieldMapper { @Override public IndexFieldData.Builder fielddataBuilder(String fullyQualifiedIndexName, Supplier searchLookup) { + emitTypesDeprecationWarning(); Function typeFunction = mapperService -> mapperService.documentMapper().type(); return new ConstantIndexFieldData.Builder(typeFunction, name(), CoreValuesSourceType.BYTES); } @@ -104,177 +98,55 @@ public class TypeFieldMapper extends MetadataFieldMapper { throw new UnsupportedOperationException("Cannot fetch values for internal field [" + name() + "]."); } - @Override - public boolean isSearchable() { - return true; - } - @Override public Query existsQuery(QueryShardContext context) { + emitTypesDeprecationWarning(); return new MatchAllDocsQuery(); } @Override - public Query termQuery(Object value, QueryShardContext context) { - return termsQuery(Arrays.asList(value), context); - } - - @Override - public Query termsQuery(List values, QueryShardContext context) { - DocumentMapper mapper = context.getMapperService().documentMapper(); - if (mapper == null) { - return new MatchNoDocsQuery("No types"); - } - BytesRef indexType = indexedValueForSearch(mapper.type()); - if (values.stream() - .map(this::indexedValueForSearch) - .anyMatch(indexType::equals)) { - if (context.getMapperService().hasNested()) { - // type filters are expected not to match nested docs - return Queries.newNonNestedFilter(context.indexVersionCreated()); - } else { - return new MatchAllDocsQuery(); - } - } else { - return new MatchNoDocsQuery("Type list does not contain the index type"); - } - } - - @Override - public Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, QueryShardContext context) { - Query result = new MatchAllDocsQuery(); - String type = context.getMapperService().documentMapper().type(); - if (type != null) { - BytesRef typeBytes = new BytesRef(type); - if (lowerTerm != null) { - int comp = indexedValueForSearch(lowerTerm).compareTo(typeBytes); - if (comp > 0 || (comp == 0 && includeLower == false)) { - result = new MatchNoDocsQuery("[_type] was lexicographically smaller than lower bound of range"); - } - } - if (upperTerm != null) { - int comp = indexedValueForSearch(upperTerm).compareTo(typeBytes); - if (comp < 0 || (comp == 0 && includeUpper == false)) { - result = new MatchNoDocsQuery("[_type] was lexicographically greater than upper bound of range"); - } - } - } - return result; - } - - @Override - public Query wildcardQuery(String value, MultiTermQuery.RewriteMethod method, boolean caseInsensitive, QueryShardContext context) { - Query termQuery = termQuery(value, context); - if (termQuery instanceof MatchNoDocsQuery || termQuery instanceof MatchAllDocsQuery) { - return termQuery; - } - - if (context.allowExpensiveQueries() == false) { - throw new ElasticsearchException("[wildcard] queries cannot be executed when '" + - ALLOW_EXPENSIVE_QUERIES.getKey() + "' is set to false."); - } - Term term = MappedFieldType.extractTerm(termQuery); - - if (caseInsensitive) { - AutomatonQuery query = AutomatonQueries.caseInsensitiveWildcardQuery(term); - QueryParsers.setRewriteMethod(query, method); - return query; - } - - WildcardQuery query = new WildcardQuery(term); - QueryParsers.setRewriteMethod(query, method); - return query; - } - } - - /** - * Specialization for a disjunction over many _type - */ - public static class TypesQuery extends Query { - // Same threshold as TermInSetQuery - private static final int BOOLEAN_REWRITE_TERM_COUNT_THRESHOLD = 16; - - private final BytesRef[] types; - - public TypesQuery(BytesRef... types) { - if (types == null) { - throw new NullPointerException("types cannot be null."); - } - if (types.length == 0) { - throw new IllegalArgumentException("types must contains at least one value."); - } - this.types = types; - } - - public BytesRef[] getTerms() { - return types; - } - - @Override - public Query rewrite(IndexReader reader) throws IOException { - final int threshold = Math.min(BOOLEAN_REWRITE_TERM_COUNT_THRESHOLD, BooleanQuery.getMaxClauseCount()); - if (types.length <= threshold) { - Set uniqueTypes = new HashSet<>(); - BooleanQuery.Builder bq = new BooleanQuery.Builder(); - int totalDocFreq = 0; - for (BytesRef type : types) { - if (uniqueTypes.add(type)) { - Term term = new Term(CONTENT_TYPE, type); - TermStates context = TermStates.build(reader.getContext(), term, true); - if (context.docFreq() == 0) { - // this _type is not present in the reader - continue; - } - totalDocFreq += context.docFreq(); - // strict equality should be enough ? - if (totalDocFreq >= reader.maxDoc()) { - assert totalDocFreq == reader.maxDoc(); - // Matches all docs since _type is a single value field - // Using a match_all query will help Lucene perform some optimizations - // For instance, match_all queries as filter clauses are automatically removed - return new MatchAllDocsQuery(); - } - bq.add(new TermQuery(term, context), BooleanClause.Occur.SHOULD); - } - } - return new ConstantScoreQuery(bq.build()); - } - return new TermInSetQuery(CONTENT_TYPE, types); - } - - @Override - public boolean equals(Object obj) { - if (sameClassAs(obj) == false) { + protected boolean matches(String pattern, boolean caseInsensitive, QueryShardContext context) { + emitTypesDeprecationWarning(); + if (type == null) { return false; } - TypesQuery that = (TypesQuery) obj; - return Arrays.equals(types, that.types); + return Regex.simpleMatch(pattern, type, caseInsensitive); } @Override - public int hashCode() { - return 31 * classHash() + Arrays.hashCode(types); - } - - @Override - public String toString(String field) { - StringBuilder builder = new StringBuilder(); - for (BytesRef type : types) { - if (builder.length() > 0) { - builder.append(' '); + public Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, + ShapeRelation relation, ZoneId timeZone, DateMathParser parser, QueryShardContext context) { + emitTypesDeprecationWarning(); + BytesRef lower = (BytesRef) lowerTerm; + BytesRef upper = (BytesRef) upperTerm; + if (includeLower) { + if (lower.utf8ToString().compareTo(type) > 0) { + return new MatchNoDocsQuery(); + } + } else { + if (lower.utf8ToString().compareTo(type) >= 0) { + return new MatchNoDocsQuery(); } - builder.append(new Term(CONTENT_TYPE, type).toString()); } - return builder.toString(); + if (includeUpper) { + if (upper.utf8ToString().compareTo(type) < 0) { + return new MatchNoDocsQuery(); + } + } else { + if (upper.utf8ToString().compareTo(type) <= 0) { + return new MatchNoDocsQuery(); + } + } + return new MatchAllDocsQuery(); } } private TypeFieldMapper() { - super(new TypeFieldType()); + super(new TypeFieldType(null)); } @Override - public void preParse(ParseContext context) throws IOException { + public void preParse(ParseContext context) { if (fieldType.indexOptions() == IndexOptions.NONE && !fieldType.stored()) { return; } diff --git a/server/src/main/java/org/elasticsearch/index/query/QueryShardContext.java b/server/src/main/java/org/elasticsearch/index/query/QueryShardContext.java index 843f0392041..b408c03d5ef 100644 --- a/server/src/main/java/org/elasticsearch/index/query/QueryShardContext.java +++ b/server/src/main/java/org/elasticsearch/index/query/QueryShardContext.java @@ -34,7 +34,6 @@ import org.elasticsearch.common.ParsingException; import org.elasticsearch.common.Strings; import org.elasticsearch.common.TriFunction; import org.elasticsearch.common.io.stream.NamedWriteableRegistry; -import org.elasticsearch.common.logging.DeprecationLogger; import org.elasticsearch.common.lucene.search.Queries; import org.elasticsearch.common.util.BigArrays; import org.elasticsearch.common.xcontent.NamedXContentRegistry; @@ -52,7 +51,6 @@ import org.elasticsearch.index.mapper.Mapper; import org.elasticsearch.index.mapper.MapperService; import org.elasticsearch.index.mapper.ObjectMapper; import org.elasticsearch.index.mapper.TextFieldMapper; -import org.elasticsearch.index.mapper.TypeFieldMapper; import org.elasticsearch.index.query.support.NestedScope; import org.elasticsearch.index.similarity.SimilarityService; import org.elasticsearch.script.Script; @@ -84,9 +82,6 @@ import static java.util.Collections.unmodifiableMap; * Context object used to create lucene queries on the shard level. */ public class QueryShardContext extends QueryRewriteContext { - private static final DeprecationLogger deprecationLogger = DeprecationLogger.getLogger(QueryShardContext.class); - public static final String TYPES_DEPRECATION_MESSAGE = "[types removal] Using the _type field " + - "in queries and aggregations is deprecated, prefer to use a field instead."; private final ScriptService scriptService; private final IndexSettings indexSettings; @@ -248,9 +243,6 @@ public class QueryShardContext extends QueryRewriteContext { } public MappedFieldType fieldMapper(String name) { - if (name.equals(TypeFieldMapper.NAME)) { - deprecationLogger.deprecate("query_with_types", TYPES_DEPRECATION_MESSAGE); - } return failIfFieldMappingNotFound(name, mapperService.fieldType(name)); } diff --git a/server/src/main/java/org/elasticsearch/index/query/TypeQueryBuilder.java b/server/src/main/java/org/elasticsearch/index/query/TypeQueryBuilder.java index 5c726ecfb01..f30a8788e44 100644 --- a/server/src/main/java/org/elasticsearch/index/query/TypeQueryBuilder.java +++ b/server/src/main/java/org/elasticsearch/index/query/TypeQueryBuilder.java @@ -28,6 +28,7 @@ import org.elasticsearch.common.ParsingException; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.logging.DeprecationLogger; +import org.elasticsearch.common.lucene.search.Queries; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.index.mapper.DocumentMapper; @@ -135,7 +136,7 @@ public class TypeQueryBuilder extends AbstractQueryBuilder { // no type means no documents return new MatchNoDocsQuery(); } else { - return documentMapper.typeFilter(context); + return Queries.newNonNestedFilter(context.indexVersionCreated()); } } diff --git a/server/src/main/java/org/elasticsearch/search/DefaultSearchContext.java b/server/src/main/java/org/elasticsearch/search/DefaultSearchContext.java index 7943c5e6b7c..6bd96439c8c 100644 --- a/server/src/main/java/org/elasticsearch/search/DefaultSearchContext.java +++ b/server/src/main/java/org/elasticsearch/search/DefaultSearchContext.java @@ -280,7 +280,6 @@ final class DefaultSearchContext extends SearchContext { } if (mapperService().hasNested() - && typeFilter == null // when a _type filter is set, it will automatically exclude nested docs && new NestedHelper(mapperService()).mightMatchNestedDocs(query) && (aliasFilter == null || new NestedHelper(mapperService()).mightMatchNestedDocs(aliasFilter))) { filters.add(Queries.newNonNestedFilter(mapperService().getIndexSettings().getIndexVersionCreated())); @@ -313,11 +312,11 @@ final class DefaultSearchContext extends SearchContext { private Query createTypeFilter(String[] types) { if (types != null && types.length >= 1) { - MappedFieldType ft = mapperService().fieldType(TypeFieldMapper.NAME); - if (ft != null) { - // ft might be null if no documents have been indexed yet - return ft.termsQuery(Arrays.asList(types), queryShardContext); + if (mapperService().documentMapper() == null) { + return null; } + MappedFieldType ft = new TypeFieldMapper.TypeFieldType(mapperService().documentMapper().type()); + return ft.termsQuery(Arrays.asList(types), queryShardContext); } return null; } diff --git a/server/src/main/java/org/elasticsearch/search/lookup/LeafFieldsLookup.java b/server/src/main/java/org/elasticsearch/search/lookup/LeafFieldsLookup.java index 69c04610320..eb440537c4a 100644 --- a/server/src/main/java/org/elasticsearch/search/lookup/LeafFieldsLookup.java +++ b/server/src/main/java/org/elasticsearch/search/lookup/LeafFieldsLookup.java @@ -144,6 +144,7 @@ public class LeafFieldsLookup implements Map { if (data.fields() == null) { List values; if (TypeFieldMapper.NAME.equals(data.fieldType().name())) { + TypeFieldMapper.emitTypesDeprecationWarning(); values = new ArrayList<>(1); final DocumentMapper mapper = mapperService.documentMapper(); if (mapper != null) { diff --git a/server/src/test/java/org/elasticsearch/index/mapper/LegacyTypeFieldMapperTests.java b/server/src/test/java/org/elasticsearch/index/mapper/LegacyTypeFieldMapperTests.java index 5bc780598a6..807fb3a2ff4 100644 --- a/server/src/test/java/org/elasticsearch/index/mapper/LegacyTypeFieldMapperTests.java +++ b/server/src/test/java/org/elasticsearch/index/mapper/LegacyTypeFieldMapperTests.java @@ -36,6 +36,7 @@ public class LegacyTypeFieldMapperTests extends ESSingleNodeTestCase { final Settings settings = Settings.builder().put(IndexMetadata.SETTING_INDEX_VERSION_CREATED.getKey(), Version.V_6_0_0).build(); return this.createIndex(index, settings); }); + assertWarnings("[types removal] Using the _type field in queries and aggregations is deprecated, prefer to use a field instead."); } } diff --git a/server/src/test/java/org/elasticsearch/index/mapper/TypeFieldMapperTests.java b/server/src/test/java/org/elasticsearch/index/mapper/TypeFieldMapperTests.java index 57ae10f7b4a..9b149b54f57 100644 --- a/server/src/test/java/org/elasticsearch/index/mapper/TypeFieldMapperTests.java +++ b/server/src/test/java/org/elasticsearch/index/mapper/TypeFieldMapperTests.java @@ -54,6 +54,7 @@ public class TypeFieldMapperTests extends ESSingleNodeTestCase { public void testDocValuesSingleType() throws Exception { testDocValues(this::createIndex); + assertWarnings("[types removal] Using the _type field in queries and aggregations is deprecated, prefer to use a field instead."); } public static void testDocValues(Function createIndex) throws IOException { diff --git a/server/src/test/java/org/elasticsearch/index/mapper/TypeFieldTypeTests.java b/server/src/test/java/org/elasticsearch/index/mapper/TypeFieldTypeTests.java index 5a6db902f63..b759c1db25d 100644 --- a/server/src/test/java/org/elasticsearch/index/mapper/TypeFieldTypeTests.java +++ b/server/src/test/java/org/elasticsearch/index/mapper/TypeFieldTypeTests.java @@ -18,66 +18,36 @@ */ package org.elasticsearch.index.mapper; -import org.apache.lucene.index.Term; import org.apache.lucene.search.MatchAllDocsQuery; import org.apache.lucene.search.MatchNoDocsQuery; import org.apache.lucene.search.Query; -import org.elasticsearch.Version; -import org.elasticsearch.cluster.metadata.IndexMetadata; -import org.elasticsearch.common.UUIDs; -import org.elasticsearch.common.lucene.search.AutomatonQueries; -import org.elasticsearch.common.lucene.search.Queries; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.index.IndexSettings; import org.elasticsearch.index.query.QueryShardContext; -import org.elasticsearch.test.VersionUtils; import org.elasticsearch.test.ESTestCase; import org.mockito.Mockito; +import java.util.Arrays; + public class TypeFieldTypeTests extends ESTestCase { public void testTermsQuery() { QueryShardContext context = Mockito.mock(QueryShardContext.class); - Version indexVersionCreated = VersionUtils.randomVersionBetween(random(), Version.V_6_0_0, Version.CURRENT); - Settings indexSettings = Settings.builder() - .put(IndexMetadata.SETTING_VERSION_CREATED, indexVersionCreated) - .put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 0) - .put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, 1) - .put(IndexMetadata.SETTING_INDEX_UUID, UUIDs.randomBase64UUID()).build(); - IndexMetadata indexMetadata = IndexMetadata.builder(IndexMetadata.INDEX_UUID_NA_VALUE).settings(indexSettings).build(); - IndexSettings mockSettings = new IndexSettings(indexMetadata, Settings.EMPTY); - Mockito.when(context.getIndexSettings()).thenReturn(mockSettings); - Mockito.when(context.indexVersionCreated()).thenReturn(indexVersionCreated); - MapperService mapperService = Mockito.mock(MapperService.class); - Mockito.when(mapperService.documentMapper()).thenReturn(null); - Mockito.when(context.getMapperService()).thenReturn(mapperService); - - TypeFieldMapper.TypeFieldType ft = TypeFieldMapper.TypeFieldType.INSTANCE; + TypeFieldMapper.TypeFieldType ft = new TypeFieldMapper.TypeFieldType("_doc"); Query query = ft.termQuery("my_type", context); assertEquals(new MatchNoDocsQuery(), query); - DocumentMapper mapper = Mockito.mock(DocumentMapper.class); - Mockito.when(mapper.type()).thenReturn("my_type"); - Mockito.when(mapperService.documentMapper()).thenReturn(mapper); - query = ft.termQuery("my_type", context); + query = ft.termQuery("_doc", context); assertEquals(new MatchAllDocsQuery(), query); - query = ft.termQueryCaseInsensitive("my_Type", context); - assertEquals(AutomatonQueries.caseInsensitiveTermQuery(new Term("_type", "my_Type")), query); + query = ft.termsQuery(Arrays.asList("_doc", "type", "foo"), context); + assertEquals(new MatchAllDocsQuery(), query); - Mockito.when(mapperService.hasNested()).thenReturn(true); - query = ft.termQuery("my_type", context); - assertEquals(Queries.newNonNestedFilter(context.indexVersionCreated()), query); - - mapper = Mockito.mock(DocumentMapper.class); - Mockito.when(mapper.type()).thenReturn("other_type"); - Mockito.when(mapperService.documentMapper()).thenReturn(mapper); - query = ft.termQuery("my_type", context); + query = ft.termsQuery(Arrays.asList("type", "foo"), context); assertEquals(new MatchNoDocsQuery(), query); - query = ft.termQueryCaseInsensitive("other_Type", context); - assertEquals(AutomatonQueries.caseInsensitiveTermQuery(new Term("_type", "other_Type")), query); + query = ft.termQueryCaseInsensitive("_DOC", context); + assertEquals(new MatchAllDocsQuery(), query); + assertWarnings("[types removal] Using the _type field in queries and aggregations is deprecated, prefer to use a field instead."); } } diff --git a/server/src/test/java/org/elasticsearch/index/query/TermQueryBuilderTests.java b/server/src/test/java/org/elasticsearch/index/query/TermQueryBuilderTests.java index 37bbae4c420..6e5721090ad 100644 --- a/server/src/test/java/org/elasticsearch/index/query/TermQueryBuilderTests.java +++ b/server/src/test/java/org/elasticsearch/index/query/TermQueryBuilderTests.java @@ -20,7 +20,6 @@ package org.elasticsearch.index.query; import com.fasterxml.jackson.core.io.JsonStringEncoder; - import org.apache.lucene.index.Term; import org.apache.lucene.search.AutomatonQuery; import org.apache.lucene.search.MatchNoDocsQuery; @@ -29,6 +28,7 @@ import org.apache.lucene.search.Query; import org.apache.lucene.search.TermQuery; import org.elasticsearch.common.ParsingException; import org.elasticsearch.index.mapper.MappedFieldType; +import org.elasticsearch.index.mapper.TypeFieldMapper; import java.io.IOException; @@ -111,7 +111,7 @@ public class TermQueryBuilderTests extends AbstractTermQueryTestCase