Generalize how queries on `_index` are handled at rewrite time (#52815)
Generalize how queries on `_index` are handled at rewrite time (#52486) Since this change refactors rewrites, I also took it as an opportunity to adrress #49254: instead of returning the same queries you would get on a keyword field when a field is unmapped, queries get rewritten to a MatchNoDocsQueryBuilder. This change exposed a couple bugs, like the fact that the percolator doesn't rewrite queries at query time, or that the significant_terms aggregation doesn't rewrite its inner filter, which I fixed. Closes #49254
This commit is contained in:
parent
ad3a3b1af9
commit
1807f86751
|
@ -24,6 +24,7 @@ import org.apache.lucene.analysis.Analyzer;
|
||||||
import org.apache.lucene.analysis.DelegatingAnalyzerWrapper;
|
import org.apache.lucene.analysis.DelegatingAnalyzerWrapper;
|
||||||
import org.apache.lucene.index.BinaryDocValues;
|
import org.apache.lucene.index.BinaryDocValues;
|
||||||
import org.apache.lucene.index.DirectoryReader;
|
import org.apache.lucene.index.DirectoryReader;
|
||||||
|
import org.apache.lucene.index.IndexReader;
|
||||||
import org.apache.lucene.index.IndexReaderContext;
|
import org.apache.lucene.index.IndexReaderContext;
|
||||||
import org.apache.lucene.index.IndexWriter;
|
import org.apache.lucene.index.IndexWriter;
|
||||||
import org.apache.lucene.index.IndexWriterConfig;
|
import org.apache.lucene.index.IndexWriterConfig;
|
||||||
|
@ -78,6 +79,7 @@ import org.elasticsearch.index.query.QueryBuilder;
|
||||||
import org.elasticsearch.index.query.QueryRewriteContext;
|
import org.elasticsearch.index.query.QueryRewriteContext;
|
||||||
import org.elasticsearch.index.query.QueryShardContext;
|
import org.elasticsearch.index.query.QueryShardContext;
|
||||||
import org.elasticsearch.index.query.QueryShardException;
|
import org.elasticsearch.index.query.QueryShardException;
|
||||||
|
import org.elasticsearch.index.query.Rewriteable;
|
||||||
import org.elasticsearch.indices.breaker.CircuitBreakerService;
|
import org.elasticsearch.indices.breaker.CircuitBreakerService;
|
||||||
import org.elasticsearch.indices.breaker.NoneCircuitBreakerService;
|
import org.elasticsearch.indices.breaker.NoneCircuitBreakerService;
|
||||||
|
|
||||||
|
@ -91,7 +93,6 @@ import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import static org.elasticsearch.percolator.PercolatorFieldMapper.parseQuery;
|
|
||||||
import static org.elasticsearch.search.SearchService.ALLOW_EXPENSIVE_QUERIES;
|
import static org.elasticsearch.search.SearchService.ALLOW_EXPENSIVE_QUERIES;
|
||||||
|
|
||||||
public class PercolateQueryBuilder extends AbstractQueryBuilder<PercolateQueryBuilder> {
|
public class PercolateQueryBuilder extends AbstractQueryBuilder<PercolateQueryBuilder> {
|
||||||
|
@ -646,9 +647,9 @@ public class PercolateQueryBuilder extends AbstractQueryBuilder<PercolateQueryBu
|
||||||
PercolatorFieldMapper.FieldType pft = (PercolatorFieldMapper.FieldType) fieldType;
|
PercolatorFieldMapper.FieldType pft = (PercolatorFieldMapper.FieldType) fieldType;
|
||||||
String name = this.name != null ? this.name : pft.name();
|
String name = this.name != null ? this.name : pft.name();
|
||||||
QueryShardContext percolateShardContext = wrap(context);
|
QueryShardContext percolateShardContext = wrap(context);
|
||||||
|
PercolatorFieldMapper.configureContext(percolateShardContext, pft.mapUnmappedFieldsAsText);;
|
||||||
PercolateQuery.QueryStore queryStore = createStore(pft.queryBuilderField,
|
PercolateQuery.QueryStore queryStore = createStore(pft.queryBuilderField,
|
||||||
percolateShardContext,
|
percolateShardContext);
|
||||||
pft.mapUnmappedFieldsAsText);
|
|
||||||
|
|
||||||
return pft.percolateQuery(name, queryStore, documents, docSearcher, excludeNestedDocuments, context.indexVersionCreated());
|
return pft.percolateQuery(name, queryStore, documents, docSearcher, excludeNestedDocuments, context.indexVersionCreated());
|
||||||
}
|
}
|
||||||
|
@ -695,8 +696,7 @@ public class PercolateQueryBuilder extends AbstractQueryBuilder<PercolateQueryBu
|
||||||
}
|
}
|
||||||
|
|
||||||
static PercolateQuery.QueryStore createStore(MappedFieldType queryBuilderFieldType,
|
static PercolateQuery.QueryStore createStore(MappedFieldType queryBuilderFieldType,
|
||||||
QueryShardContext context,
|
QueryShardContext context) {
|
||||||
boolean mapUnmappedFieldsAsString) {
|
|
||||||
Version indexVersion = context.indexVersionCreated();
|
Version indexVersion = context.indexVersionCreated();
|
||||||
NamedWriteableRegistry registry = context.getWriteableRegistry();
|
NamedWriteableRegistry registry = context.getWriteableRegistry();
|
||||||
return ctx -> {
|
return ctx -> {
|
||||||
|
@ -723,7 +723,8 @@ public class PercolateQueryBuilder extends AbstractQueryBuilder<PercolateQueryBu
|
||||||
assert valueLength > 0;
|
assert valueLength > 0;
|
||||||
QueryBuilder queryBuilder = input.readNamedWriteable(QueryBuilder.class);
|
QueryBuilder queryBuilder = input.readNamedWriteable(QueryBuilder.class);
|
||||||
assert in.read() == -1;
|
assert in.read() == -1;
|
||||||
return PercolatorFieldMapper.toQuery(context, mapUnmappedFieldsAsString, queryBuilder);
|
queryBuilder = Rewriteable.rewrite(queryBuilder, context);
|
||||||
|
return queryBuilder.toQuery(context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -739,7 +740,10 @@ public class PercolateQueryBuilder extends AbstractQueryBuilder<PercolateQueryBu
|
||||||
try (XContentParser sourceParser = xContent
|
try (XContentParser sourceParser = xContent
|
||||||
.createParser(context.getXContentRegistry(), LoggingDeprecationHandler.INSTANCE,
|
.createParser(context.getXContentRegistry(), LoggingDeprecationHandler.INSTANCE,
|
||||||
qbSource.bytes, qbSource.offset, qbSource.length)) {
|
qbSource.bytes, qbSource.offset, qbSource.length)) {
|
||||||
return parseQuery(context, mapUnmappedFieldsAsString, sourceParser);
|
QueryBuilder queryBuilder = PercolatorFieldMapper.parseQueryBuilder(sourceParser,
|
||||||
|
sourceParser.getTokenLocation());
|
||||||
|
queryBuilder = Rewriteable.rewrite(queryBuilder, context);
|
||||||
|
return queryBuilder.toQuery(context);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
|
@ -755,6 +759,13 @@ public class PercolateQueryBuilder extends AbstractQueryBuilder<PercolateQueryBu
|
||||||
static QueryShardContext wrap(QueryShardContext shardContext) {
|
static QueryShardContext wrap(QueryShardContext shardContext) {
|
||||||
return new QueryShardContext(shardContext) {
|
return new QueryShardContext(shardContext) {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IndexReader getIndexReader() {
|
||||||
|
// The reader that matters in this context is not the reader of the shard but
|
||||||
|
// the reader of the MemoryIndex. We just use `null` for simplicity.
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BitSetProducer bitsetFilter(Query query) {
|
public BitSetProducer bitsetFilter(Query query) {
|
||||||
return context -> {
|
return context -> {
|
||||||
|
|
|
@ -397,6 +397,8 @@ public class PercolatorFieldMapper extends FieldMapper {
|
||||||
throw new IllegalArgumentException("a document can only contain one percolator query");
|
throw new IllegalArgumentException("a document can only contain one percolator query");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
configureContext(queryShardContext, isMapUnmappedFieldAsText());
|
||||||
|
|
||||||
XContentParser parser = context.parser();
|
XContentParser parser = context.parser();
|
||||||
QueryBuilder queryBuilder = parseQueryBuilder(
|
QueryBuilder queryBuilder = parseQueryBuilder(
|
||||||
parser, parser.getTokenLocation()
|
parser, parser.getTokenLocation()
|
||||||
|
@ -410,7 +412,8 @@ public class PercolatorFieldMapper extends FieldMapper {
|
||||||
Version indexVersion = context.mapperService().getIndexSettings().getIndexVersionCreated();
|
Version indexVersion = context.mapperService().getIndexSettings().getIndexVersionCreated();
|
||||||
createQueryBuilderField(indexVersion, queryBuilderField, queryBuilder, context);
|
createQueryBuilderField(indexVersion, queryBuilderField, queryBuilder, context);
|
||||||
|
|
||||||
Query query = toQuery(queryShardContext, isMapUnmappedFieldAsText(), queryBuilder);
|
QueryBuilder queryBuilderForProcessing = queryBuilder.rewrite(new QueryShardContext(queryShardContext));
|
||||||
|
Query query = queryBuilderForProcessing.toQuery(queryShardContext);
|
||||||
processQuery(query, context);
|
processQuery(query, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -480,11 +483,7 @@ public class PercolatorFieldMapper extends FieldMapper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static Query parseQuery(QueryShardContext context, boolean mapUnmappedFieldsAsString, XContentParser parser) throws IOException {
|
static void configureContext(QueryShardContext context, boolean mapUnmappedFieldsAsString) {
|
||||||
return toQuery(context, mapUnmappedFieldsAsString, parseQueryBuilder(parser, parser.getTokenLocation()));
|
|
||||||
}
|
|
||||||
|
|
||||||
static Query toQuery(QueryShardContext context, boolean mapUnmappedFieldsAsString, QueryBuilder queryBuilder) throws IOException {
|
|
||||||
// This means that fields in the query need to exist in the mapping prior to registering this query
|
// This means that fields in the query need to exist in the mapping prior to registering this query
|
||||||
// The reason that this is required, is that if a field doesn't exist then the query assumes defaults, which may be undesired.
|
// The reason that this is required, is that if a field doesn't exist then the query assumes defaults, which may be undesired.
|
||||||
//
|
//
|
||||||
|
@ -499,10 +498,9 @@ public class PercolatorFieldMapper extends FieldMapper {
|
||||||
// as an analyzed string.
|
// as an analyzed string.
|
||||||
context.setAllowUnmappedFields(false);
|
context.setAllowUnmappedFields(false);
|
||||||
context.setMapUnmappedFieldAsString(mapUnmappedFieldsAsString);
|
context.setMapUnmappedFieldAsString(mapUnmappedFieldsAsString);
|
||||||
return queryBuilder.toQuery(context);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static QueryBuilder parseQueryBuilder(XContentParser parser, XContentLocation location) {
|
static QueryBuilder parseQueryBuilder(XContentParser parser, XContentLocation location) {
|
||||||
try {
|
try {
|
||||||
return parseInnerQueryBuilder(parser);
|
return parseInnerQueryBuilder(parser);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
|
|
@ -38,10 +38,12 @@ import org.elasticsearch.index.Index;
|
||||||
import org.elasticsearch.index.fielddata.plain.BytesBinaryDVIndexFieldData;
|
import org.elasticsearch.index.fielddata.plain.BytesBinaryDVIndexFieldData;
|
||||||
import org.elasticsearch.index.mapper.BinaryFieldMapper;
|
import org.elasticsearch.index.mapper.BinaryFieldMapper;
|
||||||
import org.elasticsearch.index.mapper.ContentPath;
|
import org.elasticsearch.index.mapper.ContentPath;
|
||||||
|
import org.elasticsearch.index.mapper.KeywordFieldMapper;
|
||||||
import org.elasticsearch.index.mapper.Mapper;
|
import org.elasticsearch.index.mapper.Mapper;
|
||||||
import org.elasticsearch.index.mapper.ParseContext;
|
import org.elasticsearch.index.mapper.ParseContext;
|
||||||
import org.elasticsearch.index.query.QueryShardContext;
|
import org.elasticsearch.index.query.QueryShardContext;
|
||||||
import org.elasticsearch.index.query.TermQueryBuilder;
|
import org.elasticsearch.index.query.TermQueryBuilder;
|
||||||
|
import org.elasticsearch.mock.orig.Mockito;
|
||||||
import org.elasticsearch.search.SearchModule;
|
import org.elasticsearch.search.SearchModule;
|
||||||
import org.elasticsearch.test.ESTestCase;
|
import org.elasticsearch.test.ESTestCase;
|
||||||
|
|
||||||
|
@ -93,7 +95,14 @@ public class QueryBuilderStoreTests extends ESTestCase {
|
||||||
when(queryShardContext.getXContentRegistry()).thenReturn(xContentRegistry());
|
when(queryShardContext.getXContentRegistry()).thenReturn(xContentRegistry());
|
||||||
when(queryShardContext.getForField(fieldMapper.fieldType()))
|
when(queryShardContext.getForField(fieldMapper.fieldType()))
|
||||||
.thenReturn(new BytesBinaryDVIndexFieldData(new Index("index", "uuid"), fieldMapper.name()));
|
.thenReturn(new BytesBinaryDVIndexFieldData(new Index("index", "uuid"), fieldMapper.name()));
|
||||||
PercolateQuery.QueryStore queryStore = PercolateQueryBuilder.createStore(fieldMapper.fieldType(), queryShardContext, false);
|
when(queryShardContext.fieldMapper(Mockito.anyString())).thenAnswer(invocation -> {
|
||||||
|
final String fieldName = (String) invocation.getArguments()[0];
|
||||||
|
KeywordFieldMapper.KeywordFieldType ft = new KeywordFieldMapper.KeywordFieldType();
|
||||||
|
ft.setName(fieldName);
|
||||||
|
ft.freeze();
|
||||||
|
return ft;
|
||||||
|
});
|
||||||
|
PercolateQuery.QueryStore queryStore = PercolateQueryBuilder.createStore(fieldMapper.fieldType(), queryShardContext);
|
||||||
|
|
||||||
try (IndexReader indexReader = DirectoryReader.open(directory)) {
|
try (IndexReader indexReader = DirectoryReader.open(directory)) {
|
||||||
LeafReaderContext leafContext = indexReader.leaves().get(0);
|
LeafReaderContext leafContext = indexReader.leaves().get(0);
|
||||||
|
|
|
@ -0,0 +1,123 @@
|
||||||
|
/*
|
||||||
|
* 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.search.MatchAllDocsQuery;
|
||||||
|
import org.apache.lucene.search.MatchNoDocsQuery;
|
||||||
|
import org.apache.lucene.search.MultiTermQuery;
|
||||||
|
import org.apache.lucene.search.Query;
|
||||||
|
import org.apache.lucene.util.BytesRef;
|
||||||
|
import org.elasticsearch.common.Nullable;
|
||||||
|
import org.elasticsearch.common.lucene.search.Queries;
|
||||||
|
import org.elasticsearch.common.regex.Regex;
|
||||||
|
import org.elasticsearch.index.query.QueryShardContext;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link MappedFieldType} that has the same value for all documents.
|
||||||
|
* Factory methods for queries are called at rewrite time so they should be
|
||||||
|
* cheap. In particular they should not read data from disk or perform a
|
||||||
|
* network call. Furthermore they may only return a {@link MatchAllDocsQuery}
|
||||||
|
* or a {@link MatchNoDocsQuery}.
|
||||||
|
*/
|
||||||
|
public abstract class ConstantFieldType extends MappedFieldType {
|
||||||
|
|
||||||
|
public ConstantFieldType() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConstantFieldType(ConstantFieldType other) {
|
||||||
|
super(other);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final boolean isSearchable() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final boolean isAggregatable() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final Query existsQuery(QueryShardContext context) {
|
||||||
|
return new MatchAllDocsQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return whether the constant value of this field matches the provided {@code pattern}
|
||||||
|
* as documented in {@link Regex#simpleMatch}.
|
||||||
|
*/
|
||||||
|
protected abstract boolean matches(String pattern, QueryShardContext context);
|
||||||
|
|
||||||
|
private static String valueToString(Object value) {
|
||||||
|
return value instanceof BytesRef
|
||||||
|
? ((BytesRef) value).utf8ToString()
|
||||||
|
: value.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final Query termQuery(Object value, QueryShardContext context) {
|
||||||
|
String pattern = valueToString(value);
|
||||||
|
if (matches(pattern, context)) {
|
||||||
|
return Queries.newMatchAllQuery();
|
||||||
|
} else {
|
||||||
|
return new MatchNoDocsQuery();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final Query termsQuery(List<?> values, QueryShardContext context) {
|
||||||
|
for (Object value : values) {
|
||||||
|
String pattern = valueToString(value);
|
||||||
|
if (matches(pattern, context)) {
|
||||||
|
// `terms` queries are a disjunction, so one matching term is enough
|
||||||
|
return Queries.newMatchAllQuery();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new MatchNoDocsQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final Query prefixQuery(String prefix,
|
||||||
|
@Nullable MultiTermQuery.RewriteMethod method,
|
||||||
|
QueryShardContext context) {
|
||||||
|
String pattern = prefix + "*";
|
||||||
|
if (matches(pattern, context)) {
|
||||||
|
return Queries.newMatchAllQuery();
|
||||||
|
} else {
|
||||||
|
return new MatchNoDocsQuery();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final Query wildcardQuery(String value,
|
||||||
|
@Nullable MultiTermQuery.RewriteMethod method,
|
||||||
|
QueryShardContext context) {
|
||||||
|
if (matches(value, context)) {
|
||||||
|
return Queries.newMatchAllQuery();
|
||||||
|
} else {
|
||||||
|
return new MatchNoDocsQuery();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -21,13 +21,7 @@ package org.elasticsearch.index.mapper;
|
||||||
|
|
||||||
import org.apache.lucene.index.IndexOptions;
|
import org.apache.lucene.index.IndexOptions;
|
||||||
import org.apache.lucene.index.IndexableField;
|
import org.apache.lucene.index.IndexableField;
|
||||||
import org.apache.lucene.search.MatchAllDocsQuery;
|
|
||||||
import org.apache.lucene.search.MultiTermQuery;
|
|
||||||
import org.apache.lucene.search.Query;
|
|
||||||
import org.apache.lucene.util.BytesRef;
|
|
||||||
import org.elasticsearch.common.Nullable;
|
|
||||||
import org.elasticsearch.common.lucene.Lucene;
|
import org.elasticsearch.common.lucene.Lucene;
|
||||||
import org.elasticsearch.common.lucene.search.Queries;
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.index.fielddata.IndexFieldData;
|
import org.elasticsearch.index.fielddata.IndexFieldData;
|
||||||
|
@ -89,7 +83,7 @@ public class IndexFieldMapper extends MetadataFieldMapper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static final class IndexFieldType extends MappedFieldType {
|
static final class IndexFieldType extends ConstantFieldType {
|
||||||
|
|
||||||
IndexFieldType() {}
|
IndexFieldType() {}
|
||||||
|
|
||||||
|
@ -108,81 +102,8 @@ public class IndexFieldMapper extends MetadataFieldMapper {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isSearchable() {
|
protected boolean matches(String pattern, QueryShardContext context) {
|
||||||
// The _index field is always searchable.
|
return context.indexMatches(pattern);
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Query existsQuery(QueryShardContext context) {
|
|
||||||
return new MatchAllDocsQuery();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This termQuery impl looks at the context to determine the index that
|
|
||||||
* is being queried and then returns a MATCH_ALL_QUERY or MATCH_NO_QUERY
|
|
||||||
* if the value matches this index. This can be useful if aliases or
|
|
||||||
* wildcards are used but the aim is to restrict the query to specific
|
|
||||||
* indices
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public Query termQuery(Object value, @Nullable QueryShardContext context) {
|
|
||||||
String pattern = value instanceof BytesRef
|
|
||||||
? ((BytesRef) value).utf8ToString()
|
|
||||||
: value.toString();
|
|
||||||
if (context.indexMatches(pattern)) {
|
|
||||||
// No need to OR these clauses - we can only logically be
|
|
||||||
// running in the context of just one of these index names.
|
|
||||||
return Queries.newMatchAllQuery();
|
|
||||||
} else {
|
|
||||||
return Queries.newMatchNoDocsQuery("The index [" + context.getFullyQualifiedIndex().getName() +
|
|
||||||
"] doesn't match the provided value [" + value + "].");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Query termsQuery(List values, QueryShardContext context) {
|
|
||||||
if (context == null) {
|
|
||||||
return super.termsQuery(values, context);
|
|
||||||
}
|
|
||||||
for (Object value : values) {
|
|
||||||
String pattern = value instanceof BytesRef
|
|
||||||
? ((BytesRef) value).utf8ToString()
|
|
||||||
: value.toString();
|
|
||||||
if (context.indexMatches(pattern)) {
|
|
||||||
// No need to OR these clauses - we can only logically be
|
|
||||||
// running in the context of just one of these index names.
|
|
||||||
return Queries.newMatchAllQuery();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// None of the listed index names are this one
|
|
||||||
return Queries.newMatchNoDocsQuery("The index [" + context.getFullyQualifiedIndex().getName() +
|
|
||||||
"] doesn't match the provided values [" + values + "].");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Query prefixQuery(String value,
|
|
||||||
@Nullable MultiTermQuery.RewriteMethod method,
|
|
||||||
QueryShardContext context) {
|
|
||||||
String pattern = value + "*";
|
|
||||||
if (context.indexMatches(pattern)) {
|
|
||||||
return Queries.newMatchAllQuery();
|
|
||||||
} else {
|
|
||||||
return Queries.newMatchNoDocsQuery("The index [" + context.getFullyQualifiedIndex().getName() +
|
|
||||||
"] doesn't match the provided prefix [" + value + "].");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Query wildcardQuery(String value,
|
|
||||||
@Nullable MultiTermQuery.RewriteMethod method,
|
|
||||||
QueryShardContext context) {
|
|
||||||
if (context.indexMatches(value)) {
|
|
||||||
return Queries.newMatchAllQuery();
|
|
||||||
} else {
|
|
||||||
return Queries.newMatchNoDocsQuery("The index [" + context.getFullyQualifiedIndex().getName()
|
|
||||||
+ "] doesn't match the provided pattern [" + value + "].");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
package org.elasticsearch.index.query;
|
package org.elasticsearch.index.query;
|
||||||
|
|
||||||
import org.apache.lucene.search.BoostQuery;
|
import org.apache.lucene.search.BoostQuery;
|
||||||
|
import org.apache.lucene.search.MatchNoDocsQuery;
|
||||||
import org.apache.lucene.search.Query;
|
import org.apache.lucene.search.Query;
|
||||||
import org.apache.lucene.search.spans.SpanBoostQuery;
|
import org.apache.lucene.search.spans.SpanBoostQuery;
|
||||||
import org.apache.lucene.search.spans.SpanQuery;
|
import org.apache.lucene.search.spans.SpanQuery;
|
||||||
|
@ -103,7 +104,7 @@ public abstract class AbstractQueryBuilder<QB extends AbstractQueryBuilder<QB>>
|
||||||
if (boost != DEFAULT_BOOST) {
|
if (boost != DEFAULT_BOOST) {
|
||||||
if (query instanceof SpanQuery) {
|
if (query instanceof SpanQuery) {
|
||||||
query = new SpanBoostQuery((SpanQuery) query, boost);
|
query = new SpanBoostQuery((SpanQuery) query, boost);
|
||||||
} else {
|
} else if (query instanceof MatchNoDocsQuery == false) {
|
||||||
query = new BoostQuery(query, boost);
|
query = new BoostQuery(query, boost);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -232,7 +233,7 @@ public abstract class AbstractQueryBuilder<QB extends AbstractQueryBuilder<QB>>
|
||||||
IOException {
|
IOException {
|
||||||
List<Query> queries = new ArrayList<>(queryBuilders.size());
|
List<Query> queries = new ArrayList<>(queryBuilders.size());
|
||||||
for (QueryBuilder queryBuilder : queryBuilders) {
|
for (QueryBuilder queryBuilder : queryBuilders) {
|
||||||
Query query = queryBuilder.toQuery(context);
|
Query query = queryBuilder.rewrite(context).toQuery(context);
|
||||||
if (query != null) {
|
if (query != null) {
|
||||||
queries.add(query);
|
queries.add(query);
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
|
|
||||||
package org.elasticsearch.index.query;
|
package org.elasticsearch.index.query;
|
||||||
|
|
||||||
import org.apache.lucene.index.Term;
|
|
||||||
import org.apache.lucene.search.FuzzyQuery;
|
import org.apache.lucene.search.FuzzyQuery;
|
||||||
import org.apache.lucene.search.MultiTermQuery;
|
import org.apache.lucene.search.MultiTermQuery;
|
||||||
import org.apache.lucene.search.Query;
|
import org.apache.lucene.search.Query;
|
||||||
|
@ -28,7 +27,6 @@ import org.elasticsearch.common.ParsingException;
|
||||||
import org.elasticsearch.common.Strings;
|
import org.elasticsearch.common.Strings;
|
||||||
import org.elasticsearch.common.io.stream.StreamInput;
|
import org.elasticsearch.common.io.stream.StreamInput;
|
||||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||||
import org.elasticsearch.common.lucene.BytesRefs;
|
|
||||||
import org.elasticsearch.common.unit.Fuzziness;
|
import org.elasticsearch.common.unit.Fuzziness;
|
||||||
import org.elasticsearch.common.xcontent.LoggingDeprecationHandler;
|
import org.elasticsearch.common.xcontent.LoggingDeprecationHandler;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
|
@ -322,18 +320,26 @@ public class FuzzyQueryBuilder extends AbstractQueryBuilder<FuzzyQueryBuilder> i
|
||||||
return NAME;
|
return NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected QueryBuilder doRewrite(QueryRewriteContext queryRewriteContext) throws IOException {
|
||||||
|
QueryShardContext context = queryRewriteContext.convertToShardContext();
|
||||||
|
if (context != null) {
|
||||||
|
MappedFieldType fieldType = context.fieldMapper(fieldName);
|
||||||
|
if (fieldType == null) {
|
||||||
|
return new MatchNoneQueryBuilder();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return super.doRewrite(context);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Query doToQuery(QueryShardContext context) throws IOException {
|
protected Query doToQuery(QueryShardContext context) throws IOException {
|
||||||
Query query = null;
|
|
||||||
String rewrite = this.rewrite;
|
|
||||||
MappedFieldType fieldType = context.fieldMapper(fieldName);
|
MappedFieldType fieldType = context.fieldMapper(fieldName);
|
||||||
if (fieldType != null) {
|
if (fieldType == null) {
|
||||||
query = fieldType.fuzzyQuery(value, fuzziness, prefixLength, maxExpansions, transpositions, context);
|
throw new IllegalStateException("Rewrite first");
|
||||||
}
|
|
||||||
if (query == null) {
|
|
||||||
int maxEdits = fuzziness.asDistance(BytesRefs.toString(value));
|
|
||||||
query = new FuzzyQuery(new Term(fieldName, BytesRefs.toBytesRef(value)), maxEdits, prefixLength, maxExpansions, transpositions);
|
|
||||||
}
|
}
|
||||||
|
String rewrite = this.rewrite;
|
||||||
|
Query query = fieldType.fuzzyQuery(value, fuzziness, prefixLength, maxExpansions, transpositions, context);
|
||||||
if (query instanceof MultiTermQuery) {
|
if (query instanceof MultiTermQuery) {
|
||||||
MultiTermQuery.RewriteMethod rewriteMethod = QueryParsers.parseRewriteMethod(rewrite, null,
|
MultiTermQuery.RewriteMethod rewriteMethod = QueryParsers.parseRewriteMethod(rewrite, null,
|
||||||
LoggingDeprecationHandler.INSTANCE);
|
LoggingDeprecationHandler.INSTANCE);
|
||||||
|
|
|
@ -29,7 +29,6 @@ import org.elasticsearch.common.Strings;
|
||||||
import org.elasticsearch.common.io.stream.StreamInput;
|
import org.elasticsearch.common.io.stream.StreamInput;
|
||||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||||
import org.elasticsearch.common.logging.DeprecationLogger;
|
import org.elasticsearch.common.logging.DeprecationLogger;
|
||||||
import org.elasticsearch.common.lucene.search.Queries;
|
|
||||||
import org.elasticsearch.common.xcontent.ObjectParser;
|
import org.elasticsearch.common.xcontent.ObjectParser;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
|
@ -169,31 +168,39 @@ public class IdsQueryBuilder extends AbstractQueryBuilder<IdsQueryBuilder> {
|
||||||
return NAME;
|
return NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected QueryBuilder doRewrite(QueryRewriteContext queryRewriteContext) throws IOException {
|
||||||
|
if (ids.isEmpty()) {
|
||||||
|
return new MatchNoneQueryBuilder();
|
||||||
|
}
|
||||||
|
QueryShardContext context = queryRewriteContext.convertToShardContext();
|
||||||
|
if (context != null && context.fieldMapper(IdFieldMapper.NAME) == null) {
|
||||||
|
// no mappings yet
|
||||||
|
return new MatchNoneQueryBuilder();
|
||||||
|
}
|
||||||
|
return super.doRewrite(queryRewriteContext);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Query doToQuery(QueryShardContext context) throws IOException {
|
protected Query doToQuery(QueryShardContext context) throws IOException {
|
||||||
MappedFieldType idField = context.fieldMapper(IdFieldMapper.NAME);
|
MappedFieldType idField = context.fieldMapper(IdFieldMapper.NAME);
|
||||||
if (idField == null) {
|
if (idField == null || ids.isEmpty()) {
|
||||||
return new MatchNoDocsQuery("No mappings");
|
throw new IllegalStateException("Rewrite first");
|
||||||
}
|
}
|
||||||
if (this.ids.isEmpty()) {
|
final DocumentMapper mapper = context.getMapperService().documentMapper();
|
||||||
return Queries.newMatchNoDocsQuery("Missing ids in \"" + this.getName() + "\" query.");
|
Collection<String> typesForQuery;
|
||||||
|
if (types.length == 0) {
|
||||||
|
typesForQuery = context.queryTypes();
|
||||||
|
} else if (types.length == 1 && MetaData.ALL.equals(types[0])) {
|
||||||
|
typesForQuery = Collections.singleton(mapper.type());
|
||||||
} else {
|
} else {
|
||||||
final DocumentMapper mapper = context.getMapperService().documentMapper();
|
typesForQuery = new HashSet<>(Arrays.asList(types));
|
||||||
Collection<String> typesForQuery;
|
}
|
||||||
if (types.length == 0) {
|
|
||||||
typesForQuery = context.queryTypes();
|
|
||||||
} else if (types.length == 1 && MetaData.ALL.equals(types[0])) {
|
|
||||||
typesForQuery = Collections.singleton(mapper.type());
|
|
||||||
} else {
|
|
||||||
typesForQuery = new HashSet<>(Arrays.asList(types));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typesForQuery.contains(mapper.type())) {
|
|
||||||
return idField.termsQuery(new ArrayList<>(ids), context);
|
|
||||||
} else {
|
|
||||||
return new MatchNoDocsQuery("Type mismatch");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (typesForQuery.contains(mapper.type())) {
|
||||||
|
return idField.termsQuery(new ArrayList<>(ids), context);
|
||||||
|
} else {
|
||||||
|
return new MatchNoDocsQuery("Type mismatch");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,20 +19,20 @@
|
||||||
|
|
||||||
package org.elasticsearch.index.query;
|
package org.elasticsearch.index.query;
|
||||||
|
|
||||||
import org.apache.lucene.index.Term;
|
import org.apache.lucene.search.MatchAllDocsQuery;
|
||||||
|
import org.apache.lucene.search.MatchNoDocsQuery;
|
||||||
import org.apache.lucene.search.MultiTermQuery;
|
import org.apache.lucene.search.MultiTermQuery;
|
||||||
import org.apache.lucene.search.PrefixQuery;
|
|
||||||
import org.apache.lucene.search.Query;
|
import org.apache.lucene.search.Query;
|
||||||
import org.elasticsearch.common.ParseField;
|
import org.elasticsearch.common.ParseField;
|
||||||
import org.elasticsearch.common.ParsingException;
|
import org.elasticsearch.common.ParsingException;
|
||||||
import org.elasticsearch.common.Strings;
|
import org.elasticsearch.common.Strings;
|
||||||
import org.elasticsearch.common.io.stream.StreamInput;
|
import org.elasticsearch.common.io.stream.StreamInput;
|
||||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||||
import org.elasticsearch.common.lucene.BytesRefs;
|
|
||||||
import org.elasticsearch.common.xcontent.LoggingDeprecationHandler;
|
import org.elasticsearch.common.xcontent.LoggingDeprecationHandler;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
import org.elasticsearch.index.mapper.MappedFieldType;
|
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||||
|
import org.elasticsearch.index.mapper.ConstantFieldType;
|
||||||
import org.elasticsearch.index.query.support.QueryParsers;
|
import org.elasticsearch.index.query.support.QueryParsers;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -171,14 +171,26 @@ public class PrefixQueryBuilder extends AbstractQueryBuilder<PrefixQueryBuilder>
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected QueryBuilder doRewrite(QueryRewriteContext queryRewriteContext) throws IOException {
|
protected QueryBuilder doRewrite(QueryRewriteContext queryRewriteContext) throws IOException {
|
||||||
if ("_index".equals(fieldName)) {
|
QueryShardContext context = queryRewriteContext.convertToShardContext();
|
||||||
// Special-case optimisation for canMatch phase:
|
if (context != null) {
|
||||||
// We can skip querying this shard if the index name doesn't match the value of this query on the "_index" field.
|
MappedFieldType fieldType = context.fieldMapper(this.fieldName);
|
||||||
QueryShardContext shardContext = queryRewriteContext.convertToShardContext();
|
if (fieldType == null) {
|
||||||
if (shardContext != null && shardContext.indexMatches(value + "*") == false) {
|
|
||||||
return new MatchNoneQueryBuilder();
|
return new MatchNoneQueryBuilder();
|
||||||
|
} else if (fieldType instanceof ConstantFieldType) {
|
||||||
|
// This logic is correct for all field types, but by only applying it to constant
|
||||||
|
// fields we also have the guarantee that it doesn't perform I/O, which is important
|
||||||
|
// since rewrites might happen on a network thread.
|
||||||
|
Query query = fieldType.prefixQuery(value, null, context); // the rewrite method doesn't matter
|
||||||
|
if (query instanceof MatchAllDocsQuery) {
|
||||||
|
return new MatchAllQueryBuilder();
|
||||||
|
} else if (query instanceof MatchNoDocsQuery) {
|
||||||
|
return new MatchNoneQueryBuilder();
|
||||||
|
} else {
|
||||||
|
assert false : "Constant fields must produce match-all or match-none queries, got " + query ;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return super.doRewrite(queryRewriteContext);
|
return super.doRewrite(queryRewriteContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,20 +198,11 @@ public class PrefixQueryBuilder extends AbstractQueryBuilder<PrefixQueryBuilder>
|
||||||
protected Query doToQuery(QueryShardContext context) throws IOException {
|
protected Query doToQuery(QueryShardContext context) throws IOException {
|
||||||
MultiTermQuery.RewriteMethod method = QueryParsers.parseRewriteMethod(rewrite, null, LoggingDeprecationHandler.INSTANCE);
|
MultiTermQuery.RewriteMethod method = QueryParsers.parseRewriteMethod(rewrite, null, LoggingDeprecationHandler.INSTANCE);
|
||||||
|
|
||||||
Query query = null;
|
|
||||||
MappedFieldType fieldType = context.fieldMapper(fieldName);
|
MappedFieldType fieldType = context.fieldMapper(fieldName);
|
||||||
if (fieldType != null) {
|
if (fieldType == null) {
|
||||||
query = fieldType.prefixQuery(value, method, context);
|
throw new IllegalStateException("Rewrite first");
|
||||||
}
|
}
|
||||||
if (query == null) {
|
return fieldType.prefixQuery(value, method, context);
|
||||||
PrefixQuery prefixQuery = new PrefixQuery(new Term(fieldName, BytesRefs.toBytesRef(value)));
|
|
||||||
if (method != null) {
|
|
||||||
prefixQuery.setRewriteMethod(method);
|
|
||||||
}
|
|
||||||
query = prefixQuery;
|
|
||||||
}
|
|
||||||
|
|
||||||
return query;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -21,7 +21,6 @@ package org.elasticsearch.index.query;
|
||||||
|
|
||||||
import org.apache.lucene.search.MatchNoDocsQuery;
|
import org.apache.lucene.search.MatchNoDocsQuery;
|
||||||
import org.apache.lucene.search.Query;
|
import org.apache.lucene.search.Query;
|
||||||
import org.apache.lucene.search.TermRangeQuery;
|
|
||||||
import org.apache.lucene.util.BytesRef;
|
import org.apache.lucene.util.BytesRef;
|
||||||
import org.elasticsearch.common.ParseField;
|
import org.elasticsearch.common.ParseField;
|
||||||
import org.elasticsearch.common.ParsingException;
|
import org.elasticsearch.common.ParsingException;
|
||||||
|
@ -29,14 +28,12 @@ import org.elasticsearch.common.Strings;
|
||||||
import org.elasticsearch.common.geo.ShapeRelation;
|
import org.elasticsearch.common.geo.ShapeRelation;
|
||||||
import org.elasticsearch.common.io.stream.StreamInput;
|
import org.elasticsearch.common.io.stream.StreamInput;
|
||||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||||
import org.elasticsearch.common.lucene.BytesRefs;
|
|
||||||
import org.elasticsearch.common.time.DateFormatter;
|
import org.elasticsearch.common.time.DateFormatter;
|
||||||
import org.elasticsearch.common.time.DateMathParser;
|
import org.elasticsearch.common.time.DateMathParser;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
import org.elasticsearch.index.mapper.FieldNamesFieldMapper;
|
import org.elasticsearch.index.mapper.FieldNamesFieldMapper;
|
||||||
import org.elasticsearch.index.mapper.MappedFieldType;
|
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||||
import org.elasticsearch.index.mapper.MapperService;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.time.DateTimeException;
|
import java.time.DateTimeException;
|
||||||
|
@ -432,21 +429,23 @@ public class RangeQueryBuilder extends AbstractQueryBuilder<RangeQueryBuilder> i
|
||||||
// Overridable for testing only
|
// Overridable for testing only
|
||||||
protected MappedFieldType.Relation getRelation(QueryRewriteContext queryRewriteContext) throws IOException {
|
protected MappedFieldType.Relation getRelation(QueryRewriteContext queryRewriteContext) throws IOException {
|
||||||
QueryShardContext shardContext = queryRewriteContext.convertToShardContext();
|
QueryShardContext shardContext = queryRewriteContext.convertToShardContext();
|
||||||
// If the context is null we are not on the shard and cannot
|
if (shardContext != null) {
|
||||||
// rewrite so just pretend there is an intersection so that the rewrite is a noop
|
final MappedFieldType fieldType = shardContext.fieldMapper(fieldName);
|
||||||
if (shardContext == null || shardContext.getIndexReader() == null) {
|
if (fieldType == null) {
|
||||||
return MappedFieldType.Relation.INTERSECTS;
|
return MappedFieldType.Relation.DISJOINT;
|
||||||
}
|
}
|
||||||
final MapperService mapperService = shardContext.getMapperService();
|
if (shardContext.getIndexReader() == null) {
|
||||||
final MappedFieldType fieldType = mapperService.fieldType(fieldName);
|
// No reader, this may happen e.g. for percolator queries.
|
||||||
if (fieldType == null) {
|
return MappedFieldType.Relation.INTERSECTS;
|
||||||
// no field means we have no values
|
}
|
||||||
return MappedFieldType.Relation.DISJOINT;
|
|
||||||
} else {
|
|
||||||
DateMathParser dateMathParser = getForceDateParser();
|
DateMathParser dateMathParser = getForceDateParser();
|
||||||
return fieldType.isFieldWithinQuery(shardContext.getIndexReader(), from, to, includeLower,
|
return fieldType.isFieldWithinQuery(shardContext.getIndexReader(), from, to, includeLower,
|
||||||
includeUpper, timeZone, dateMathParser, queryRewriteContext);
|
includeUpper, timeZone, dateMathParser, queryRewriteContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Not on the shard, we have no way to know what the relation is.
|
||||||
|
return MappedFieldType.Relation.INTERSECTS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -490,26 +489,14 @@ public class RangeQueryBuilder extends AbstractQueryBuilder<RangeQueryBuilder> i
|
||||||
return ExistsQueryBuilder.newFilter(context, fieldName);
|
return ExistsQueryBuilder.newFilter(context, fieldName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Query query = null;
|
|
||||||
MappedFieldType mapper = context.fieldMapper(this.fieldName);
|
MappedFieldType mapper = context.fieldMapper(this.fieldName);
|
||||||
if (mapper != null) {
|
if (mapper == null) {
|
||||||
DateMathParser forcedDateParser = getForceDateParser();
|
throw new IllegalStateException("Rewrite first");
|
||||||
query = mapper.rangeQuery(
|
|
||||||
from, to, includeLower, includeUpper,
|
|
||||||
relation, timeZone, forcedDateParser, context);
|
|
||||||
} else {
|
|
||||||
if (timeZone != null) {
|
|
||||||
throw new QueryShardException(context, "[range] time_zone can not be applied to non unmapped field ["
|
|
||||||
+ fieldName + "]");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
DateMathParser forcedDateParser = getForceDateParser();
|
||||||
if (query == null) {
|
return mapper.rangeQuery(
|
||||||
query = new TermRangeQuery(this.fieldName,
|
from, to, includeLower, includeUpper,
|
||||||
BytesRefs.toBytesRef(from), BytesRefs.toBytesRef(to),
|
relation, timeZone, forcedDateParser, context);
|
||||||
includeLower, includeUpper);
|
|
||||||
}
|
|
||||||
return query;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -126,11 +126,16 @@ public class SpanMultiTermQueryBuilder extends AbstractQueryBuilder<SpanMultiTer
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Query doToQuery(QueryShardContext context) throws IOException {
|
protected Query doToQuery(QueryShardContext context) throws IOException {
|
||||||
if (multiTermQueryBuilder instanceof PrefixQueryBuilder) {
|
// We do the rewrite in toQuery to not have to deal with the case when a multi-term builder rewrites to a non-multi-term
|
||||||
|
// builder.
|
||||||
|
QueryBuilder multiTermQueryBuilder = Rewriteable.rewrite(this.multiTermQueryBuilder, context);
|
||||||
|
if (multiTermQueryBuilder instanceof MatchNoneQueryBuilder) {
|
||||||
|
return new SpanMatchNoDocsQuery(this.multiTermQueryBuilder.fieldName(), "Inner query rewrote to match_none");
|
||||||
|
} else if (multiTermQueryBuilder instanceof PrefixQueryBuilder) {
|
||||||
PrefixQueryBuilder prefixBuilder = (PrefixQueryBuilder) multiTermQueryBuilder;
|
PrefixQueryBuilder prefixBuilder = (PrefixQueryBuilder) multiTermQueryBuilder;
|
||||||
MappedFieldType fieldType = context.fieldMapper(multiTermQueryBuilder.fieldName());
|
MappedFieldType fieldType = context.fieldMapper(prefixBuilder.fieldName());
|
||||||
if (fieldType == null) {
|
if (fieldType == null) {
|
||||||
return new SpanMatchNoDocsQuery(multiTermQueryBuilder.fieldName(), "unknown field");
|
throw new IllegalStateException("Rewrite first");
|
||||||
}
|
}
|
||||||
final SpanMultiTermQueryWrapper.SpanRewriteMethod spanRewriteMethod;
|
final SpanMultiTermQueryWrapper.SpanRewriteMethod spanRewriteMethod;
|
||||||
if (prefixBuilder.rewrite() != null) {
|
if (prefixBuilder.rewrite() != null) {
|
||||||
|
@ -159,7 +164,7 @@ public class SpanMultiTermQueryBuilder extends AbstractQueryBuilder<SpanMultiTer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (subQuery instanceof MatchNoDocsQuery) {
|
if (subQuery instanceof MatchNoDocsQuery) {
|
||||||
return new SpanMatchNoDocsQuery(multiTermQueryBuilder.fieldName(), subQuery.toString());
|
return new SpanMatchNoDocsQuery(this.multiTermQueryBuilder.fieldName(), subQuery.toString());
|
||||||
} else if (subQuery instanceof MultiTermQuery == false) {
|
} else if (subQuery instanceof MultiTermQuery == false) {
|
||||||
throw new UnsupportedOperationException("unsupported inner query, should be "
|
throw new UnsupportedOperationException("unsupported inner query, should be "
|
||||||
+ MultiTermQuery.class.getName() + " but was " + subQuery.getClass().getName());
|
+ MultiTermQuery.class.getName() + " but was " + subQuery.getClass().getName());
|
||||||
|
|
|
@ -19,15 +19,15 @@
|
||||||
|
|
||||||
package org.elasticsearch.index.query;
|
package org.elasticsearch.index.query;
|
||||||
|
|
||||||
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.apache.lucene.search.Query;
|
||||||
import org.apache.lucene.search.TermQuery;
|
|
||||||
import org.elasticsearch.common.ParseField;
|
import org.elasticsearch.common.ParseField;
|
||||||
import org.elasticsearch.common.ParsingException;
|
import org.elasticsearch.common.ParsingException;
|
||||||
import org.elasticsearch.common.io.stream.StreamInput;
|
import org.elasticsearch.common.io.stream.StreamInput;
|
||||||
import org.elasticsearch.common.lucene.BytesRefs;
|
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
import org.elasticsearch.index.mapper.MappedFieldType;
|
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||||
|
import org.elasticsearch.index.mapper.ConstantFieldType;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
@ -132,12 +132,23 @@ public class TermQueryBuilder extends BaseTermQueryBuilder<TermQueryBuilder> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected QueryBuilder doRewrite(QueryRewriteContext queryRewriteContext) throws IOException {
|
protected QueryBuilder doRewrite(QueryRewriteContext queryRewriteContext) throws IOException {
|
||||||
if ("_index".equals(fieldName)) {
|
QueryShardContext context = queryRewriteContext.convertToShardContext();
|
||||||
// Special-case optimisation for canMatch phase:
|
if (context != null) {
|
||||||
// We can skip querying this shard if the index name doesn't match the value of this query on the "_index" field.
|
MappedFieldType fieldType = context.fieldMapper(this.fieldName);
|
||||||
QueryShardContext shardContext = queryRewriteContext.convertToShardContext();
|
if (fieldType == null) {
|
||||||
if (shardContext != null && shardContext.indexMatches(BytesRefs.toString(value)) == false) {
|
|
||||||
return new MatchNoneQueryBuilder();
|
return new MatchNoneQueryBuilder();
|
||||||
|
} else if (fieldType instanceof ConstantFieldType) {
|
||||||
|
// This logic is correct for all field types, but by only applying it to constant
|
||||||
|
// fields we also have the guarantee that it doesn't perform I/O, which is important
|
||||||
|
// since rewrites might happen on a network thread.
|
||||||
|
Query query = fieldType.termQuery(value, context);
|
||||||
|
if (query instanceof MatchAllDocsQuery) {
|
||||||
|
return new MatchAllQueryBuilder();
|
||||||
|
} else if (query instanceof MatchNoDocsQuery) {
|
||||||
|
return new MatchNoneQueryBuilder();
|
||||||
|
} else {
|
||||||
|
assert false : "Constant fields must produce match-all or match-none queries, got " + query ;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return super.doRewrite(queryRewriteContext);
|
return super.doRewrite(queryRewriteContext);
|
||||||
|
@ -145,15 +156,11 @@ public class TermQueryBuilder extends BaseTermQueryBuilder<TermQueryBuilder> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Query doToQuery(QueryShardContext context) throws IOException {
|
protected Query doToQuery(QueryShardContext context) throws IOException {
|
||||||
Query query = null;
|
|
||||||
MappedFieldType mapper = context.fieldMapper(this.fieldName);
|
MappedFieldType mapper = context.fieldMapper(this.fieldName);
|
||||||
if (mapper != null) {
|
if (mapper == null) {
|
||||||
query = mapper.termQuery(this.value, context);
|
throw new IllegalStateException("Rewrite first");
|
||||||
}
|
}
|
||||||
if (query == null) {
|
return mapper.termQuery(this.value, context);
|
||||||
query = new TermQuery(new Term(this.fieldName, BytesRefs.toBytesRef(this.value)));
|
|
||||||
}
|
|
||||||
return query;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -20,8 +20,9 @@
|
||||||
package org.elasticsearch.index.query;
|
package org.elasticsearch.index.query;
|
||||||
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.lucene.search.MatchAllDocsQuery;
|
||||||
|
import org.apache.lucene.search.MatchNoDocsQuery;
|
||||||
import org.apache.lucene.search.Query;
|
import org.apache.lucene.search.Query;
|
||||||
import org.apache.lucene.search.TermInSetQuery;
|
|
||||||
import org.apache.lucene.util.BytesRef;
|
import org.apache.lucene.util.BytesRef;
|
||||||
import org.apache.lucene.util.BytesRefBuilder;
|
import org.apache.lucene.util.BytesRefBuilder;
|
||||||
import org.apache.lucene.util.SetOnce;
|
import org.apache.lucene.util.SetOnce;
|
||||||
|
@ -35,13 +36,12 @@ import org.elasticsearch.common.io.stream.BytesStreamOutput;
|
||||||
import org.elasticsearch.common.io.stream.StreamInput;
|
import org.elasticsearch.common.io.stream.StreamInput;
|
||||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||||
import org.elasticsearch.common.logging.DeprecationLogger;
|
import org.elasticsearch.common.logging.DeprecationLogger;
|
||||||
import org.elasticsearch.common.lucene.BytesRefs;
|
|
||||||
import org.elasticsearch.common.lucene.search.Queries;
|
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
import org.elasticsearch.common.xcontent.support.XContentMapValues;
|
import org.elasticsearch.common.xcontent.support.XContentMapValues;
|
||||||
import org.elasticsearch.index.IndexSettings;
|
import org.elasticsearch.index.IndexSettings;
|
||||||
import org.elasticsearch.index.mapper.MappedFieldType;
|
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||||
|
import org.elasticsearch.index.mapper.ConstantFieldType;
|
||||||
import org.elasticsearch.indices.TermsLookup;
|
import org.elasticsearch.indices.TermsLookup;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -432,12 +432,9 @@ public class TermsQueryBuilder extends AbstractQueryBuilder<TermsQueryBuilder> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Query doToQuery(QueryShardContext context) throws IOException {
|
protected Query doToQuery(QueryShardContext context) throws IOException {
|
||||||
if (termsLookup != null || supplier != null) {
|
if (termsLookup != null || supplier != null || values == null || values.isEmpty()) {
|
||||||
throw new UnsupportedOperationException("query must be rewritten first");
|
throw new UnsupportedOperationException("query must be rewritten first");
|
||||||
}
|
}
|
||||||
if (values == null || values.isEmpty()) {
|
|
||||||
return Queries.newMatchNoDocsQuery("No terms supplied for \"" + getName() + "\" query.");
|
|
||||||
}
|
|
||||||
int maxTermsCount = context.getIndexSettings().getMaxTermsCount();
|
int maxTermsCount = context.getIndexSettings().getMaxTermsCount();
|
||||||
if (values.size() > maxTermsCount){
|
if (values.size() > maxTermsCount){
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
|
@ -446,16 +443,10 @@ public class TermsQueryBuilder extends AbstractQueryBuilder<TermsQueryBuilder> {
|
||||||
IndexSettings.MAX_TERMS_COUNT_SETTING.getKey() + "] index level setting.");
|
IndexSettings.MAX_TERMS_COUNT_SETTING.getKey() + "] index level setting.");
|
||||||
}
|
}
|
||||||
MappedFieldType fieldType = context.fieldMapper(fieldName);
|
MappedFieldType fieldType = context.fieldMapper(fieldName);
|
||||||
|
if (fieldType == null) {
|
||||||
if (fieldType != null) {
|
throw new IllegalStateException("Rewrite first");
|
||||||
return fieldType.termsQuery(values, context);
|
|
||||||
} else {
|
|
||||||
BytesRef[] filterValues = new BytesRef[values.size()];
|
|
||||||
for (int i = 0; i < filterValues.length; i++) {
|
|
||||||
filterValues[i] = BytesRefs.toBytesRef(values.get(i));
|
|
||||||
}
|
|
||||||
return new TermInSetQuery(fieldName, filterValues);
|
|
||||||
}
|
}
|
||||||
|
return fieldType.termsQuery(values, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fetch(TermsLookup termsLookup, Client client, ActionListener<List<Object>> actionListener) {
|
private void fetch(TermsLookup termsLookup, Client client, ActionListener<List<Object>> actionListener) {
|
||||||
|
@ -499,21 +490,31 @@ public class TermsQueryBuilder extends AbstractQueryBuilder<TermsQueryBuilder> {
|
||||||
})));
|
})));
|
||||||
return new TermsQueryBuilder(this.fieldName, supplier::get);
|
return new TermsQueryBuilder(this.fieldName, supplier::get);
|
||||||
}
|
}
|
||||||
if ("_index".equals(this.fieldName) && values != null) {
|
|
||||||
// Special-case optimisation for canMatch phase:
|
if (values == null || values.isEmpty()) {
|
||||||
// We can skip querying this shard if the index name doesn't match any of the search terms.
|
return new MatchNoneQueryBuilder();
|
||||||
QueryShardContext shardContext = queryRewriteContext.convertToShardContext();
|
}
|
||||||
if (shardContext != null) {
|
|
||||||
for (Object localValue : values) {
|
QueryShardContext context = queryRewriteContext.convertToShardContext();
|
||||||
if (shardContext.indexMatches(BytesRefs.toString(localValue))) {
|
if (context != null) {
|
||||||
// We can match - at least one index name matches
|
MappedFieldType fieldType = context.fieldMapper(this.fieldName);
|
||||||
return this;
|
if (fieldType == null) {
|
||||||
}
|
|
||||||
}
|
|
||||||
// all index names are invalid - no possibility of a match on this shard.
|
|
||||||
return new MatchNoneQueryBuilder();
|
return new MatchNoneQueryBuilder();
|
||||||
|
} else if (fieldType instanceof ConstantFieldType) {
|
||||||
|
// This logic is correct for all field types, but by only applying it to constant
|
||||||
|
// fields we also have the guarantee that it doesn't perform I/O, which is important
|
||||||
|
// since rewrites might happen on a network thread.
|
||||||
|
Query query = fieldType.termsQuery(values, context);
|
||||||
|
if (query instanceof MatchAllDocsQuery) {
|
||||||
|
return new MatchAllQueryBuilder();
|
||||||
|
} else if (query instanceof MatchNoDocsQuery) {
|
||||||
|
return new MatchNoneQueryBuilder();
|
||||||
|
} else {
|
||||||
|
assert false : "Constant fields must produce match-all or match-none queries, got " + query ;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.index.query;
|
package org.elasticsearch.index.query;
|
||||||
|
|
||||||
|
import org.apache.lucene.search.MatchAllDocsQuery;
|
||||||
import org.apache.lucene.search.MatchNoDocsQuery;
|
import org.apache.lucene.search.MatchNoDocsQuery;
|
||||||
import org.apache.lucene.search.MultiTermQuery;
|
import org.apache.lucene.search.MultiTermQuery;
|
||||||
import org.apache.lucene.search.Query;
|
import org.apache.lucene.search.Query;
|
||||||
|
@ -27,11 +28,11 @@ import org.elasticsearch.common.ParsingException;
|
||||||
import org.elasticsearch.common.Strings;
|
import org.elasticsearch.common.Strings;
|
||||||
import org.elasticsearch.common.io.stream.StreamInput;
|
import org.elasticsearch.common.io.stream.StreamInput;
|
||||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||||
import org.elasticsearch.common.lucene.BytesRefs;
|
|
||||||
import org.elasticsearch.common.xcontent.LoggingDeprecationHandler;
|
import org.elasticsearch.common.xcontent.LoggingDeprecationHandler;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
import org.elasticsearch.index.mapper.MappedFieldType;
|
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||||
|
import org.elasticsearch.index.mapper.ConstantFieldType;
|
||||||
import org.elasticsearch.index.query.support.QueryParsers;
|
import org.elasticsearch.index.query.support.QueryParsers;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -182,14 +183,26 @@ public class WildcardQueryBuilder extends AbstractQueryBuilder<WildcardQueryBuil
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected QueryBuilder doRewrite(QueryRewriteContext queryRewriteContext) throws IOException {
|
protected QueryBuilder doRewrite(QueryRewriteContext queryRewriteContext) throws IOException {
|
||||||
if ("_index".equals(fieldName)) {
|
QueryShardContext context = queryRewriteContext.convertToShardContext();
|
||||||
// Special-case optimisation for canMatch phase:
|
if (context != null) {
|
||||||
// We can skip querying this shard if the index name doesn't match the value of this query on the "_index" field.
|
MappedFieldType fieldType = context.fieldMapper(this.fieldName);
|
||||||
QueryShardContext shardContext = queryRewriteContext.convertToShardContext();
|
if (fieldType == null) {
|
||||||
if (shardContext != null && shardContext.indexMatches(BytesRefs.toString(value)) == false) {
|
|
||||||
return new MatchNoneQueryBuilder();
|
return new MatchNoneQueryBuilder();
|
||||||
|
} else if (fieldType instanceof ConstantFieldType) {
|
||||||
|
// This logic is correct for all field types, but by only applying it to constant
|
||||||
|
// fields we also have the guarantee that it doesn't perform I/O, which is important
|
||||||
|
// since rewrites might happen on a network thread.
|
||||||
|
Query query = fieldType.wildcardQuery(value, null, context); // the rewrite method doesn't matter
|
||||||
|
if (query instanceof MatchAllDocsQuery) {
|
||||||
|
return new MatchAllQueryBuilder();
|
||||||
|
} else if (query instanceof MatchNoDocsQuery) {
|
||||||
|
return new MatchNoneQueryBuilder();
|
||||||
|
} else {
|
||||||
|
assert false : "Constant fields must produce match-all or match-none queries, got " + query ;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return super.doRewrite(queryRewriteContext);
|
return super.doRewrite(queryRewriteContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,7 +211,7 @@ public class WildcardQueryBuilder extends AbstractQueryBuilder<WildcardQueryBuil
|
||||||
MappedFieldType fieldType = context.fieldMapper(fieldName);
|
MappedFieldType fieldType = context.fieldMapper(fieldName);
|
||||||
|
|
||||||
if (fieldType == null) {
|
if (fieldType == null) {
|
||||||
return new MatchNoDocsQuery("unknown field [" + fieldName + "]");
|
throw new IllegalStateException("Rewrite first");
|
||||||
}
|
}
|
||||||
|
|
||||||
MultiTermQuery.RewriteMethod method = QueryParsers.parseRewriteMethod(
|
MultiTermQuery.RewriteMethod method = QueryParsers.parseRewriteMethod(
|
||||||
|
|
|
@ -26,6 +26,7 @@ import org.elasticsearch.common.xcontent.ObjectParser;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
import org.elasticsearch.index.query.QueryBuilder;
|
import org.elasticsearch.index.query.QueryBuilder;
|
||||||
|
import org.elasticsearch.index.query.QueryRewriteContext;
|
||||||
import org.elasticsearch.index.query.QueryShardContext;
|
import org.elasticsearch.index.query.QueryShardContext;
|
||||||
import org.elasticsearch.search.aggregations.AggregationBuilder;
|
import org.elasticsearch.search.aggregations.AggregationBuilder;
|
||||||
import org.elasticsearch.search.aggregations.AggregatorFactories.Builder;
|
import org.elasticsearch.search.aggregations.AggregatorFactories.Builder;
|
||||||
|
@ -127,10 +128,23 @@ public class SignificantTermsAggregationBuilder extends ValuesSourceAggregationB
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AggregationBuilder shallowCopy(Builder factoriesBuilder, Map<String, Object> metaData) {
|
protected SignificantTermsAggregationBuilder shallowCopy(Builder factoriesBuilder, Map<String, Object> metaData) {
|
||||||
return new SignificantTermsAggregationBuilder(this, factoriesBuilder, metaData);
|
return new SignificantTermsAggregationBuilder(this, factoriesBuilder, metaData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected AggregationBuilder doRewrite(QueryRewriteContext queryShardContext) throws IOException {
|
||||||
|
if (filterBuilder != null) {
|
||||||
|
QueryBuilder rewrittenFilter = filterBuilder.rewrite(queryShardContext);
|
||||||
|
if (rewrittenFilter != filterBuilder) {
|
||||||
|
SignificantTermsAggregationBuilder rewritten = shallowCopy(factoriesBuilder, metaData);
|
||||||
|
rewritten.backgroundFilter(rewrittenFilter);
|
||||||
|
return rewritten;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return super.doRewrite(queryShardContext);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void innerWriteTo(StreamOutput out) throws IOException {
|
protected void innerWriteTo(StreamOutput out) throws IOException {
|
||||||
bucketCountThresholds.writeTo(out);
|
bucketCountThresholds.writeTo(out);
|
||||||
|
|
|
@ -22,6 +22,7 @@ package org.elasticsearch.index.query;
|
||||||
import org.apache.lucene.search.BooleanClause;
|
import org.apache.lucene.search.BooleanClause;
|
||||||
import org.apache.lucene.search.BooleanQuery;
|
import org.apache.lucene.search.BooleanQuery;
|
||||||
import org.apache.lucene.search.MatchAllDocsQuery;
|
import org.apache.lucene.search.MatchAllDocsQuery;
|
||||||
|
import org.apache.lucene.search.MatchNoDocsQuery;
|
||||||
import org.apache.lucene.search.Query;
|
import org.apache.lucene.search.Query;
|
||||||
import org.elasticsearch.common.ParsingException;
|
import org.elasticsearch.common.ParsingException;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
|
@ -85,7 +86,7 @@ public class BoolQueryBuilderTests extends AbstractQueryTestCase<BoolQueryBuilde
|
||||||
|
|
||||||
if (clauses.isEmpty()) {
|
if (clauses.isEmpty()) {
|
||||||
assertThat(query, instanceOf(MatchAllDocsQuery.class));
|
assertThat(query, instanceOf(MatchAllDocsQuery.class));
|
||||||
} else {
|
} else if (query instanceof MatchNoDocsQuery == false) {
|
||||||
assertThat(query, instanceOf(BooleanQuery.class));
|
assertThat(query, instanceOf(BooleanQuery.class));
|
||||||
BooleanQuery booleanQuery = (BooleanQuery) query;
|
BooleanQuery booleanQuery = (BooleanQuery) query;
|
||||||
if (queryBuilder.adjustPureNegative()) {
|
if (queryBuilder.adjustPureNegative()) {
|
||||||
|
@ -113,7 +114,7 @@ public class BoolQueryBuilderTests extends AbstractQueryTestCase<BoolQueryBuilde
|
||||||
BooleanClause.Occur occur, QueryShardContext context) throws IOException {
|
BooleanClause.Occur occur, QueryShardContext context) throws IOException {
|
||||||
List<BooleanClause> clauses = new ArrayList<>();
|
List<BooleanClause> clauses = new ArrayList<>();
|
||||||
for (QueryBuilder query : queryBuilders) {
|
for (QueryBuilder query : queryBuilders) {
|
||||||
Query innerQuery = query.toQuery(context);
|
Query innerQuery = query.rewrite(context).toQuery(context);
|
||||||
if (innerQuery != null) {
|
if (innerQuery != null) {
|
||||||
clauses.add(new BooleanClause(innerQuery, occur));
|
clauses.add(new BooleanClause(innerQuery, occur));
|
||||||
}
|
}
|
||||||
|
@ -195,15 +196,15 @@ public class BoolQueryBuilderTests extends AbstractQueryTestCase<BoolQueryBuilde
|
||||||
public void testMinShouldMatchBiggerThanNumberOfShouldClauses() throws Exception {
|
public void testMinShouldMatchBiggerThanNumberOfShouldClauses() throws Exception {
|
||||||
BooleanQuery bq = (BooleanQuery) parseQuery(
|
BooleanQuery bq = (BooleanQuery) parseQuery(
|
||||||
boolQuery()
|
boolQuery()
|
||||||
.should(termQuery("foo", "bar"))
|
.should(termQuery(STRING_FIELD_NAME, "bar"))
|
||||||
.should(termQuery("foo2", "bar2"))
|
.should(termQuery(STRING_FIELD_NAME_2, "bar2"))
|
||||||
.minimumShouldMatch("3")).toQuery(createShardContext());
|
.minimumShouldMatch("3")).toQuery(createShardContext());
|
||||||
assertEquals(3, bq.getMinimumNumberShouldMatch());
|
assertEquals(3, bq.getMinimumNumberShouldMatch());
|
||||||
|
|
||||||
bq = (BooleanQuery) parseQuery(
|
bq = (BooleanQuery) parseQuery(
|
||||||
boolQuery()
|
boolQuery()
|
||||||
.should(termQuery("foo", "bar"))
|
.should(termQuery(STRING_FIELD_NAME, "bar"))
|
||||||
.should(termQuery("foo2", "bar2"))
|
.should(termQuery(STRING_FIELD_NAME_2, "bar2"))
|
||||||
.minimumShouldMatch(3)).toQuery(createShardContext());
|
.minimumShouldMatch(3)).toQuery(createShardContext());
|
||||||
assertEquals(3, bq.getMinimumNumberShouldMatch());
|
assertEquals(3, bq.getMinimumNumberShouldMatch());
|
||||||
}
|
}
|
||||||
|
@ -211,8 +212,8 @@ public class BoolQueryBuilderTests extends AbstractQueryTestCase<BoolQueryBuilde
|
||||||
public void testMinShouldMatchDisableCoord() throws Exception {
|
public void testMinShouldMatchDisableCoord() throws Exception {
|
||||||
BooleanQuery bq = (BooleanQuery) parseQuery(
|
BooleanQuery bq = (BooleanQuery) parseQuery(
|
||||||
boolQuery()
|
boolQuery()
|
||||||
.should(termQuery("foo", "bar"))
|
.should(termQuery(STRING_FIELD_NAME, "bar"))
|
||||||
.should(termQuery("foo2", "bar2"))
|
.should(termQuery(STRING_FIELD_NAME, "bar2"))
|
||||||
.minimumShouldMatch("3")).toQuery(createShardContext());
|
.minimumShouldMatch("3")).toQuery(createShardContext());
|
||||||
assertEquals(3, bq.getMinimumNumberShouldMatch());
|
assertEquals(3, bq.getMinimumNumberShouldMatch());
|
||||||
}
|
}
|
||||||
|
@ -292,22 +293,22 @@ public class BoolQueryBuilderTests extends AbstractQueryTestCase<BoolQueryBuilde
|
||||||
boolean mustRewrite = false;
|
boolean mustRewrite = false;
|
||||||
if (randomBoolean()) {
|
if (randomBoolean()) {
|
||||||
mustRewrite = true;
|
mustRewrite = true;
|
||||||
boolQueryBuilder.must(new WrapperQueryBuilder(new TermsQueryBuilder("foo", "must").toString()));
|
boolQueryBuilder.must(new WrapperQueryBuilder(new TermsQueryBuilder(STRING_FIELD_NAME, "must").toString()));
|
||||||
}
|
}
|
||||||
if (randomBoolean()) {
|
if (randomBoolean()) {
|
||||||
mustRewrite = true;
|
mustRewrite = true;
|
||||||
boolQueryBuilder.should(new WrapperQueryBuilder(new TermsQueryBuilder("foo", "should").toString()));
|
boolQueryBuilder.should(new WrapperQueryBuilder(new TermsQueryBuilder(STRING_FIELD_NAME, "should").toString()));
|
||||||
}
|
}
|
||||||
if (randomBoolean()) {
|
if (randomBoolean()) {
|
||||||
mustRewrite = true;
|
mustRewrite = true;
|
||||||
boolQueryBuilder.filter(new WrapperQueryBuilder(new TermsQueryBuilder("foo", "filter").toString()));
|
boolQueryBuilder.filter(new WrapperQueryBuilder(new TermsQueryBuilder(STRING_FIELD_NAME, "filter").toString()));
|
||||||
}
|
}
|
||||||
if (randomBoolean()) {
|
if (randomBoolean()) {
|
||||||
mustRewrite = true;
|
mustRewrite = true;
|
||||||
boolQueryBuilder.mustNot(new WrapperQueryBuilder(new TermsQueryBuilder("foo", "must_not").toString()));
|
boolQueryBuilder.mustNot(new WrapperQueryBuilder(new TermsQueryBuilder(STRING_FIELD_NAME, "must_not").toString()));
|
||||||
}
|
}
|
||||||
if (mustRewrite == false && randomBoolean()) {
|
if (mustRewrite == false && randomBoolean()) {
|
||||||
boolQueryBuilder.must(new TermsQueryBuilder("foo", "no_rewrite"));
|
boolQueryBuilder.must(new TermsQueryBuilder(STRING_FIELD_NAME, "no_rewrite"));
|
||||||
}
|
}
|
||||||
QueryBuilder rewritten = boolQueryBuilder.rewrite(createShardContext());
|
QueryBuilder rewritten = boolQueryBuilder.rewrite(createShardContext());
|
||||||
if (mustRewrite == false && boolQueryBuilder.must().isEmpty()) {
|
if (mustRewrite == false && boolQueryBuilder.must().isEmpty()) {
|
||||||
|
@ -318,16 +319,16 @@ public class BoolQueryBuilderTests extends AbstractQueryTestCase<BoolQueryBuilde
|
||||||
if (mustRewrite) {
|
if (mustRewrite) {
|
||||||
assertNotSame(rewrite, boolQueryBuilder);
|
assertNotSame(rewrite, boolQueryBuilder);
|
||||||
if (boolQueryBuilder.must().isEmpty() == false) {
|
if (boolQueryBuilder.must().isEmpty() == false) {
|
||||||
assertEquals(new TermsQueryBuilder("foo", "must"), rewrite.must().get(0));
|
assertEquals(new TermsQueryBuilder(STRING_FIELD_NAME, "must"), rewrite.must().get(0));
|
||||||
}
|
}
|
||||||
if (boolQueryBuilder.should().isEmpty() == false) {
|
if (boolQueryBuilder.should().isEmpty() == false) {
|
||||||
assertEquals(new TermsQueryBuilder("foo", "should"), rewrite.should().get(0));
|
assertEquals(new TermsQueryBuilder(STRING_FIELD_NAME, "should"), rewrite.should().get(0));
|
||||||
}
|
}
|
||||||
if (boolQueryBuilder.mustNot().isEmpty() == false) {
|
if (boolQueryBuilder.mustNot().isEmpty() == false) {
|
||||||
assertEquals(new TermsQueryBuilder("foo", "must_not"), rewrite.mustNot().get(0));
|
assertEquals(new TermsQueryBuilder(STRING_FIELD_NAME, "must_not"), rewrite.mustNot().get(0));
|
||||||
}
|
}
|
||||||
if (boolQueryBuilder.filter().isEmpty() == false) {
|
if (boolQueryBuilder.filter().isEmpty() == false) {
|
||||||
assertEquals(new TermsQueryBuilder("foo", "filter"), rewrite.filter().get(0));
|
assertEquals(new TermsQueryBuilder(STRING_FIELD_NAME, "filter"), rewrite.filter().get(0));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
assertSame(rewrite, boolQueryBuilder);
|
assertSame(rewrite, boolQueryBuilder);
|
||||||
|
@ -360,14 +361,14 @@ public class BoolQueryBuilderTests extends AbstractQueryTestCase<BoolQueryBuilde
|
||||||
assertEquals(new MatchNoneQueryBuilder(), rewritten);
|
assertEquals(new MatchNoneQueryBuilder(), rewritten);
|
||||||
|
|
||||||
boolQueryBuilder = new BoolQueryBuilder();
|
boolQueryBuilder = new BoolQueryBuilder();
|
||||||
boolQueryBuilder.must(new TermQueryBuilder("foo","bar"));
|
boolQueryBuilder.must(new TermQueryBuilder(STRING_FIELD_NAME,"bar"));
|
||||||
boolQueryBuilder.filter(new WrapperQueryBuilder(new WrapperQueryBuilder(new MatchNoneQueryBuilder().toString()).toString()));
|
boolQueryBuilder.filter(new WrapperQueryBuilder(new WrapperQueryBuilder(new MatchNoneQueryBuilder().toString()).toString()));
|
||||||
rewritten = boolQueryBuilder.rewrite(createShardContext());
|
rewritten = boolQueryBuilder.rewrite(createShardContext());
|
||||||
assertEquals(new MatchNoneQueryBuilder(), rewritten);
|
assertEquals(new MatchNoneQueryBuilder(), rewritten);
|
||||||
|
|
||||||
boolQueryBuilder = new BoolQueryBuilder();
|
boolQueryBuilder = new BoolQueryBuilder();
|
||||||
boolQueryBuilder.must(new TermQueryBuilder("foo","bar"));
|
boolQueryBuilder.must(new TermQueryBuilder(STRING_FIELD_NAME,"bar"));
|
||||||
boolQueryBuilder.filter(new BoolQueryBuilder().should(new TermQueryBuilder("foo","bar"))
|
boolQueryBuilder.filter(new BoolQueryBuilder().should(new TermQueryBuilder(STRING_FIELD_NAME,"bar"))
|
||||||
.filter(new MatchNoneQueryBuilder()));
|
.filter(new MatchNoneQueryBuilder()));
|
||||||
rewritten = Rewriteable.rewrite(boolQueryBuilder, createShardContext());
|
rewritten = Rewriteable.rewrite(boolQueryBuilder, createShardContext());
|
||||||
assertEquals(new MatchNoneQueryBuilder(), rewritten);
|
assertEquals(new MatchNoneQueryBuilder(), rewritten);
|
||||||
|
@ -378,7 +379,7 @@ public class BoolQueryBuilderTests extends AbstractQueryTestCase<BoolQueryBuilde
|
||||||
assertEquals(new MatchNoneQueryBuilder(), rewritten);
|
assertEquals(new MatchNoneQueryBuilder(), rewritten);
|
||||||
|
|
||||||
boolQueryBuilder = new BoolQueryBuilder();
|
boolQueryBuilder = new BoolQueryBuilder();
|
||||||
boolQueryBuilder.should(new TermQueryBuilder("foo", "bar"));
|
boolQueryBuilder.should(new TermQueryBuilder(STRING_FIELD_NAME, "bar"));
|
||||||
boolQueryBuilder.should(new WrapperQueryBuilder(new MatchNoneQueryBuilder().toString()));
|
boolQueryBuilder.should(new WrapperQueryBuilder(new MatchNoneQueryBuilder().toString()));
|
||||||
rewritten = Rewriteable.rewrite(boolQueryBuilder, createShardContext());
|
rewritten = Rewriteable.rewrite(boolQueryBuilder, createShardContext());
|
||||||
assertNotEquals(new MatchNoneQueryBuilder(), rewritten);
|
assertNotEquals(new MatchNoneQueryBuilder(), rewritten);
|
||||||
|
@ -387,4 +388,16 @@ public class BoolQueryBuilderTests extends AbstractQueryTestCase<BoolQueryBuilde
|
||||||
rewritten = Rewriteable.rewrite(boolQueryBuilder, createShardContext());
|
rewritten = Rewriteable.rewrite(boolQueryBuilder, createShardContext());
|
||||||
assertNotEquals(new MatchNoneQueryBuilder(), rewritten);
|
assertNotEquals(new MatchNoneQueryBuilder(), rewritten);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void testMustRewrite() throws IOException {
|
||||||
|
QueryShardContext context = createShardContext();
|
||||||
|
context.setAllowUnmappedFields(true);
|
||||||
|
TermQueryBuilder termQuery = new TermQueryBuilder("unmapped_field", 42);
|
||||||
|
BoolQueryBuilder boolQuery = new BoolQueryBuilder();
|
||||||
|
boolQuery.must(termQuery);
|
||||||
|
IllegalStateException e = expectThrows(IllegalStateException.class,
|
||||||
|
() -> boolQuery.toQuery(context));
|
||||||
|
assertEquals("Rewrite first", e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,8 +40,8 @@ public class BoostingQueryBuilderTests extends AbstractQueryTestCase<BoostingQue
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doAssertLuceneQuery(BoostingQueryBuilder queryBuilder, Query query, QueryShardContext context) throws IOException {
|
protected void doAssertLuceneQuery(BoostingQueryBuilder queryBuilder, Query query, QueryShardContext context) throws IOException {
|
||||||
Query positive = queryBuilder.positiveQuery().toQuery(context);
|
Query positive = queryBuilder.positiveQuery().rewrite(context).toQuery(context);
|
||||||
Query negative = queryBuilder.negativeQuery().toQuery(context);
|
Query negative = queryBuilder.negativeQuery().rewrite(context).toQuery(context);
|
||||||
if (positive == null || negative == null) {
|
if (positive == null || negative == null) {
|
||||||
assertThat(query, nullValue());
|
assertThat(query, nullValue());
|
||||||
} else {
|
} else {
|
||||||
|
@ -103,4 +103,22 @@ public class BoostingQueryBuilderTests extends AbstractQueryTestCase<BoostingQue
|
||||||
assertEquals(new BoostingQueryBuilder(positive.rewrite(createShardContext()), negative.rewrite(createShardContext())), rewrite);
|
assertEquals(new BoostingQueryBuilder(positive.rewrite(createShardContext()), negative.rewrite(createShardContext())), rewrite);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void testMustRewrite() throws IOException {
|
||||||
|
QueryShardContext context = createShardContext();
|
||||||
|
context.setAllowUnmappedFields(true);
|
||||||
|
|
||||||
|
BoostingQueryBuilder queryBuilder1 = new BoostingQueryBuilder(
|
||||||
|
new TermQueryBuilder("unmapped_field", "foo"), new MatchNoneQueryBuilder());
|
||||||
|
IllegalStateException e = expectThrows(IllegalStateException.class,
|
||||||
|
() -> queryBuilder1.toQuery(context));
|
||||||
|
assertEquals("Rewrite first", e.getMessage());
|
||||||
|
|
||||||
|
BoostingQueryBuilder queryBuilder2 = new BoostingQueryBuilder(
|
||||||
|
new MatchAllQueryBuilder(), new TermQueryBuilder("unmapped_field", "foo"));
|
||||||
|
e = expectThrows(IllegalStateException.class,
|
||||||
|
() -> queryBuilder2.toQuery(context));
|
||||||
|
assertEquals("Rewrite first", e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
package org.elasticsearch.index.query;
|
package org.elasticsearch.index.query;
|
||||||
|
|
||||||
import org.apache.lucene.search.ConstantScoreQuery;
|
import org.apache.lucene.search.ConstantScoreQuery;
|
||||||
|
import org.apache.lucene.search.MatchNoDocsQuery;
|
||||||
import org.apache.lucene.search.Query;
|
import org.apache.lucene.search.Query;
|
||||||
import org.elasticsearch.common.ParsingException;
|
import org.elasticsearch.common.ParsingException;
|
||||||
import org.elasticsearch.test.AbstractQueryTestCase;
|
import org.elasticsearch.test.AbstractQueryTestCase;
|
||||||
|
@ -41,9 +42,11 @@ public class ConstantScoreQueryBuilderTests extends AbstractQueryTestCase<Consta
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doAssertLuceneQuery(ConstantScoreQueryBuilder queryBuilder, Query query, QueryShardContext context) throws IOException {
|
protected void doAssertLuceneQuery(ConstantScoreQueryBuilder queryBuilder, Query query, QueryShardContext context) throws IOException {
|
||||||
Query innerQuery = queryBuilder.innerQuery().toQuery(context);
|
Query innerQuery = queryBuilder.innerQuery().rewrite(context).toQuery(context);
|
||||||
if (innerQuery == null) {
|
if (innerQuery == null) {
|
||||||
assertThat(query, nullValue());
|
assertThat(query, nullValue());
|
||||||
|
} else if (innerQuery instanceof MatchNoDocsQuery) {
|
||||||
|
assertThat(query, instanceOf(MatchNoDocsQuery.class));
|
||||||
} else {
|
} else {
|
||||||
assertThat(query, instanceOf(ConstantScoreQuery.class));
|
assertThat(query, instanceOf(ConstantScoreQuery.class));
|
||||||
ConstantScoreQuery constantScoreQuery = (ConstantScoreQuery) query;
|
ConstantScoreQuery constantScoreQuery = (ConstantScoreQuery) query;
|
||||||
|
@ -107,4 +110,14 @@ public class ConstantScoreQueryBuilderTests extends AbstractQueryTestCase<Consta
|
||||||
QueryBuilder rewrite = constantScoreQueryBuilder.rewrite(createShardContext());
|
QueryBuilder rewrite = constantScoreQueryBuilder.rewrite(createShardContext());
|
||||||
assertEquals(rewrite, new MatchNoneQueryBuilder());
|
assertEquals(rewrite, new MatchNoneQueryBuilder());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void testMustRewrite() throws IOException {
|
||||||
|
QueryShardContext context = createShardContext();
|
||||||
|
context.setAllowUnmappedFields(true);
|
||||||
|
ConstantScoreQueryBuilder queryBuilder = new ConstantScoreQueryBuilder(new TermQueryBuilder("unmapped_field", "foo"));
|
||||||
|
IllegalStateException e = expectThrows(IllegalStateException.class,
|
||||||
|
() -> queryBuilder.toQuery(context));
|
||||||
|
assertEquals("Rewrite first", e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -164,4 +164,14 @@ public class IdsQueryBuilderTests extends AbstractQueryTestCase<IdsQueryBuilder>
|
||||||
}
|
}
|
||||||
return query;
|
return query;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void testMustRewrite() throws IOException {
|
||||||
|
QueryShardContext context = createShardContextWithNoType();
|
||||||
|
context.setAllowUnmappedFields(true);
|
||||||
|
IdsQueryBuilder queryBuilder = createTestQueryBuilder();
|
||||||
|
IllegalStateException e = expectThrows(IllegalStateException.class,
|
||||||
|
() -> queryBuilder.toQuery(context));
|
||||||
|
assertEquals("Rewrite first", e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,8 +57,6 @@ import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
public class NestedQueryBuilderTests extends AbstractQueryTestCase<NestedQueryBuilder> {
|
public class NestedQueryBuilderTests extends AbstractQueryTestCase<NestedQueryBuilder> {
|
||||||
|
|
||||||
boolean requiresRewrite = false;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void initializeAdditionalMappings(MapperService mapperService) throws IOException {
|
protected void initializeAdditionalMappings(MapperService mapperService) throws IOException {
|
||||||
mapperService.merge("_doc", new CompressedXContent(Strings.toString(PutMappingRequest.buildFromSimplifiedDef("_doc",
|
mapperService.merge("_doc", new CompressedXContent(Strings.toString(PutMappingRequest.buildFromSimplifiedDef("_doc",
|
||||||
|
@ -79,10 +77,6 @@ public class NestedQueryBuilderTests extends AbstractQueryTestCase<NestedQueryBu
|
||||||
@Override
|
@Override
|
||||||
protected NestedQueryBuilder doCreateTestQueryBuilder() {
|
protected NestedQueryBuilder doCreateTestQueryBuilder() {
|
||||||
QueryBuilder innerQueryBuilder = RandomQueryBuilder.createQuery(random());
|
QueryBuilder innerQueryBuilder = RandomQueryBuilder.createQuery(random());
|
||||||
if (randomBoolean()) {
|
|
||||||
requiresRewrite = true;
|
|
||||||
innerQueryBuilder = new WrapperQueryBuilder(innerQueryBuilder.toString());
|
|
||||||
}
|
|
||||||
NestedQueryBuilder nqb = new NestedQueryBuilder("nested1", innerQueryBuilder,
|
NestedQueryBuilder nqb = new NestedQueryBuilder("nested1", innerQueryBuilder,
|
||||||
RandomPicks.randomFrom(random(), ScoreMode.values()));
|
RandomPicks.randomFrom(random(), ScoreMode.values()));
|
||||||
nqb.ignoreUnmapped(randomBoolean());
|
nqb.ignoreUnmapped(randomBoolean());
|
||||||
|
@ -186,13 +180,14 @@ public class NestedQueryBuilderTests extends AbstractQueryTestCase<NestedQueryBu
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void testMustRewrite() throws IOException {
|
public void testMustRewrite() throws IOException {
|
||||||
try {
|
QueryShardContext context = createShardContext();
|
||||||
super.testMustRewrite();
|
context.setAllowUnmappedFields(true);
|
||||||
} catch (UnsupportedOperationException e) {
|
TermQueryBuilder innerQueryBuilder = new TermQueryBuilder("nested1.unmapped_field", "foo");
|
||||||
if (requiresRewrite == false) {
|
NestedQueryBuilder nestedQueryBuilder = new NestedQueryBuilder("nested1", innerQueryBuilder,
|
||||||
throw e;
|
RandomPicks.randomFrom(random(), ScoreMode.values()));
|
||||||
}
|
IllegalStateException e = expectThrows(IllegalStateException.class,
|
||||||
}
|
() -> nestedQueryBuilder.toQuery(context));
|
||||||
|
assertEquals("Rewrite first", e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testIgnoreUnmapped() throws IOException {
|
public void testIgnoreUnmapped() throws IOException {
|
||||||
|
|
|
@ -20,11 +20,13 @@
|
||||||
package org.elasticsearch.index.query;
|
package org.elasticsearch.index.query;
|
||||||
|
|
||||||
import org.apache.lucene.index.Term;
|
import org.apache.lucene.index.Term;
|
||||||
|
import org.apache.lucene.search.MatchNoDocsQuery;
|
||||||
import org.apache.lucene.search.MultiTermQuery;
|
import org.apache.lucene.search.MultiTermQuery;
|
||||||
import org.apache.lucene.search.PrefixQuery;
|
import org.apache.lucene.search.PrefixQuery;
|
||||||
import org.apache.lucene.search.Query;
|
import org.apache.lucene.search.Query;
|
||||||
import org.elasticsearch.common.ParsingException;
|
import org.elasticsearch.common.ParsingException;
|
||||||
import org.elasticsearch.test.AbstractQueryTestCase;
|
import org.elasticsearch.test.AbstractQueryTestCase;
|
||||||
|
import org.hamcrest.Matchers;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
@ -68,12 +70,14 @@ public class PrefixQueryBuilderTests extends AbstractQueryTestCase<PrefixQueryBu
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doAssertLuceneQuery(PrefixQueryBuilder queryBuilder, Query query, QueryShardContext context) throws IOException {
|
protected void doAssertLuceneQuery(PrefixQueryBuilder queryBuilder, Query query, QueryShardContext context) throws IOException {
|
||||||
assertThat(query, instanceOf(PrefixQuery.class));
|
assertThat(query, Matchers.anyOf(instanceOf(PrefixQuery.class), instanceOf(MatchNoDocsQuery.class)));
|
||||||
PrefixQuery prefixQuery = (PrefixQuery) query;
|
if (context.fieldMapper(queryBuilder.fieldName()) != null) { // The field is mapped
|
||||||
|
PrefixQuery prefixQuery = (PrefixQuery) query;
|
||||||
|
|
||||||
String expectedFieldName = expectedFieldName(queryBuilder.fieldName());
|
String expectedFieldName = expectedFieldName(queryBuilder.fieldName());
|
||||||
assertThat(prefixQuery.getPrefix().field(), equalTo(expectedFieldName));
|
assertThat(prefixQuery.getPrefix().field(), equalTo(expectedFieldName));
|
||||||
assertThat(prefixQuery.getPrefix().text(), equalTo(queryBuilder.value()));
|
assertThat(prefixQuery.getPrefix().text(), equalTo(queryBuilder.value()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testIllegalArguments() {
|
public void testIllegalArguments() {
|
||||||
|
@ -88,10 +92,10 @@ public class PrefixQueryBuilderTests extends AbstractQueryTestCase<PrefixQueryBu
|
||||||
|
|
||||||
public void testBlendedRewriteMethod() throws IOException {
|
public void testBlendedRewriteMethod() throws IOException {
|
||||||
String rewrite = "top_terms_blended_freqs_10";
|
String rewrite = "top_terms_blended_freqs_10";
|
||||||
Query parsedQuery = parseQuery(prefixQuery("field", "val").rewrite(rewrite)).toQuery(createShardContext());
|
Query parsedQuery = parseQuery(prefixQuery(STRING_FIELD_NAME, "val").rewrite(rewrite)).toQuery(createShardContext());
|
||||||
assertThat(parsedQuery, instanceOf(PrefixQuery.class));
|
assertThat(parsedQuery, instanceOf(PrefixQuery.class));
|
||||||
PrefixQuery prefixQuery = (PrefixQuery) parsedQuery;
|
PrefixQuery prefixQuery = (PrefixQuery) parsedQuery;
|
||||||
assertThat(prefixQuery.getPrefix(), equalTo(new Term("field", "val")));
|
assertThat(prefixQuery.getPrefix(), equalTo(new Term(STRING_FIELD_NAME, "val")));
|
||||||
assertThat(prefixQuery.getRewriteMethod(), instanceOf(MultiTermQuery.TopTermsBlendedFreqScoringRewrite.class));
|
assertThat(prefixQuery.getRewriteMethod(), instanceOf(MultiTermQuery.TopTermsBlendedFreqScoringRewrite.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,7 +157,16 @@ public class PrefixQueryBuilderTests extends AbstractQueryTestCase<PrefixQueryBu
|
||||||
PrefixQueryBuilder query = prefixQuery("_index", getIndex().getName());
|
PrefixQueryBuilder query = prefixQuery("_index", getIndex().getName());
|
||||||
QueryShardContext queryShardContext = createShardContext();
|
QueryShardContext queryShardContext = createShardContext();
|
||||||
QueryBuilder rewritten = query.rewrite(queryShardContext);
|
QueryBuilder rewritten = query.rewrite(queryShardContext);
|
||||||
assertThat(rewritten, instanceOf(PrefixQueryBuilder.class));
|
assertThat(rewritten, instanceOf(MatchAllQueryBuilder.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void testMustRewrite() throws IOException {
|
||||||
|
QueryShardContext context = createShardContext();
|
||||||
|
context.setAllowUnmappedFields(true);
|
||||||
|
PrefixQueryBuilder queryBuilder = new PrefixQueryBuilder("unmapped_field", "foo");
|
||||||
|
IllegalStateException e = expectThrows(IllegalStateException.class,
|
||||||
|
() -> queryBuilder.toQuery(context));
|
||||||
|
assertEquals("Rewrite first", e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,7 +53,6 @@ import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import static org.elasticsearch.index.query.QueryBuilders.rangeQuery;
|
import static org.elasticsearch.index.query.QueryBuilders.rangeQuery;
|
||||||
import static org.hamcrest.Matchers.containsString;
|
|
||||||
import static org.hamcrest.Matchers.equalTo;
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
import static org.hamcrest.Matchers.instanceOf;
|
import static org.hamcrest.Matchers.instanceOf;
|
||||||
import static org.hamcrest.Matchers.sameInstance;
|
import static org.hamcrest.Matchers.sameInstance;
|
||||||
|
@ -245,16 +244,6 @@ public class RangeQueryBuilderTests extends AbstractQueryTestCase<RangeQueryBuil
|
||||||
expectThrows(IllegalArgumentException.class, () -> rangeQueryBuilder.format("badFormat"));
|
expectThrows(IllegalArgumentException.class, () -> rangeQueryBuilder.format("badFormat"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Specifying a timezone together with an unmapped field should throw an exception.
|
|
||||||
*/
|
|
||||||
public void testToQueryUnmappedWithTimezone() throws QueryShardException {
|
|
||||||
RangeQueryBuilder query = new RangeQueryBuilder("bogus_field");
|
|
||||||
query.from(1).to(10).timeZone("UTC");
|
|
||||||
QueryShardException e = expectThrows(QueryShardException.class, () -> query.toQuery(createShardContext()));
|
|
||||||
assertThat(e.getMessage(), containsString("[range] time_zone can not be applied"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testToQueryNumericField() throws IOException {
|
public void testToQueryNumericField() throws IOException {
|
||||||
Query parsedQuery = rangeQuery(INT_FIELD_NAME).from(23).to(54).includeLower(true).includeUpper(false).toQuery(createShardContext());
|
Query parsedQuery = rangeQuery(INT_FIELD_NAME).from(23).to(54).includeLower(true).includeUpper(false).toQuery(createShardContext());
|
||||||
// since age is automatically registered in data, we encode it as numeric
|
// since age is automatically registered in data, we encode it as numeric
|
||||||
|
|
|
@ -99,6 +99,19 @@ public class ScriptScoreQueryBuilderTests extends AbstractQueryTestCase<ScriptSc
|
||||||
assertFalse("query should not be cacheable: " + queryBuilder.toString(), context.isCacheable());
|
assertFalse("query should not be cacheable: " + queryBuilder.toString(), context.isCacheable());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void testMustRewrite() throws IOException {
|
||||||
|
QueryShardContext context = createShardContext();
|
||||||
|
context.setAllowUnmappedFields(true);
|
||||||
|
TermQueryBuilder termQueryBuilder = new TermQueryBuilder("unmapped_field", "foo");
|
||||||
|
String scriptStr = "1";
|
||||||
|
Script script = new Script(ScriptType.INLINE, MockScriptEngine.NAME, scriptStr, Collections.emptyMap());
|
||||||
|
ScriptScoreQueryBuilder scriptScoreQueryBuilder = new ScriptScoreQueryBuilder(termQueryBuilder, script);
|
||||||
|
IllegalStateException e = expectThrows(IllegalStateException.class,
|
||||||
|
() -> scriptScoreQueryBuilder.toQuery(context));
|
||||||
|
assertEquals("Rewrite first", e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
public void testDisallowExpensiveQueries() {
|
public void testDisallowExpensiveQueries() {
|
||||||
QueryShardContext queryShardContext = mock(QueryShardContext.class);
|
QueryShardContext queryShardContext = mock(QueryShardContext.class);
|
||||||
when(queryShardContext.allowExpensiveQueries()).thenReturn(false);
|
when(queryShardContext.allowExpensiveQueries()).thenReturn(false);
|
||||||
|
|
|
@ -90,7 +90,8 @@ public class SpanMultiTermQueryBuilderTests extends AbstractQueryTestCase<SpanMu
|
||||||
if (query instanceof SpanMatchNoDocsQuery) {
|
if (query instanceof SpanMatchNoDocsQuery) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
assertThat(query, either(instanceOf(SpanMultiTermQueryWrapper.class)).or(instanceOf(FieldMaskingSpanQuery.class)));
|
assertThat(query, either(instanceOf(SpanMultiTermQueryWrapper.class))
|
||||||
|
.or(instanceOf(FieldMaskingSpanQuery.class)));
|
||||||
if (query instanceof SpanMultiTermQueryWrapper) {
|
if (query instanceof SpanMultiTermQueryWrapper) {
|
||||||
SpanMultiTermQueryWrapper wrapper = (SpanMultiTermQueryWrapper) query;
|
SpanMultiTermQueryWrapper wrapper = (SpanMultiTermQueryWrapper) query;
|
||||||
Query innerQuery = queryBuilder.innerQuery().toQuery(context);
|
Query innerQuery = queryBuilder.innerQuery().toQuery(context);
|
||||||
|
|
|
@ -21,11 +21,11 @@ package org.elasticsearch.index.query;
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.io.JsonStringEncoder;
|
import com.fasterxml.jackson.core.io.JsonStringEncoder;
|
||||||
import org.apache.lucene.index.Term;
|
import org.apache.lucene.index.Term;
|
||||||
|
import org.apache.lucene.search.MatchNoDocsQuery;
|
||||||
import org.apache.lucene.search.PointRangeQuery;
|
import org.apache.lucene.search.PointRangeQuery;
|
||||||
import org.apache.lucene.search.Query;
|
import org.apache.lucene.search.Query;
|
||||||
import org.apache.lucene.search.TermQuery;
|
import org.apache.lucene.search.TermQuery;
|
||||||
import org.elasticsearch.common.ParsingException;
|
import org.elasticsearch.common.ParsingException;
|
||||||
import org.elasticsearch.common.lucene.BytesRefs;
|
|
||||||
import org.elasticsearch.index.mapper.MappedFieldType;
|
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -91,7 +91,7 @@ public class TermQueryBuilderTests extends AbstractTermQueryTestCase<TermQueryBu
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doAssertLuceneQuery(TermQueryBuilder queryBuilder, Query query, QueryShardContext context) throws IOException {
|
protected void doAssertLuceneQuery(TermQueryBuilder queryBuilder, Query query, QueryShardContext context) throws IOException {
|
||||||
assertThat(query, either(instanceOf(TermQuery.class)).or(instanceOf(PointRangeQuery.class)));
|
assertThat(query, either(instanceOf(TermQuery.class)).or(instanceOf(PointRangeQuery.class)).or(instanceOf(MatchNoDocsQuery.class)));
|
||||||
MappedFieldType mapper = context.fieldMapper(queryBuilder.fieldName());
|
MappedFieldType mapper = context.fieldMapper(queryBuilder.fieldName());
|
||||||
if (query instanceof TermQuery) {
|
if (query instanceof TermQuery) {
|
||||||
TermQuery termQuery = (TermQuery) query;
|
TermQuery termQuery = (TermQuery) query;
|
||||||
|
@ -99,14 +99,12 @@ public class TermQueryBuilderTests extends AbstractTermQueryTestCase<TermQueryBu
|
||||||
String expectedFieldName = expectedFieldName(queryBuilder.fieldName());
|
String expectedFieldName = expectedFieldName(queryBuilder.fieldName());
|
||||||
assertThat(termQuery.getTerm().field(), equalTo(expectedFieldName));
|
assertThat(termQuery.getTerm().field(), equalTo(expectedFieldName));
|
||||||
|
|
||||||
if (mapper != null) {
|
Term term = ((TermQuery) mapper.termQuery(queryBuilder.value(), null)).getTerm();
|
||||||
Term term = ((TermQuery) mapper.termQuery(queryBuilder.value(), null)).getTerm();
|
assertThat(termQuery.getTerm(), equalTo(term));
|
||||||
assertThat(termQuery.getTerm(), equalTo(term));
|
} else if (mapper != null) {
|
||||||
} else {
|
|
||||||
assertThat(termQuery.getTerm().bytes(), equalTo(BytesRefs.toBytesRef(queryBuilder.value())));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
assertEquals(query, mapper.termQuery(queryBuilder.value(), null));
|
assertEquals(query, mapper.termQuery(queryBuilder.value(), null));
|
||||||
|
} else {
|
||||||
|
assertThat(query, instanceOf(MatchNoDocsQuery.class));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,6 +183,16 @@ public class TermQueryBuilderTests extends AbstractTermQueryTestCase<TermQueryBu
|
||||||
TermQueryBuilder query = QueryBuilders.termQuery("_index", getIndex().getName());
|
TermQueryBuilder query = QueryBuilders.termQuery("_index", getIndex().getName());
|
||||||
QueryShardContext queryShardContext = createShardContext();
|
QueryShardContext queryShardContext = createShardContext();
|
||||||
QueryBuilder rewritten = query.rewrite(queryShardContext);
|
QueryBuilder rewritten = query.rewrite(queryShardContext);
|
||||||
assertThat(rewritten, instanceOf(TermQueryBuilder.class));
|
assertThat(rewritten, instanceOf(MatchAllQueryBuilder.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void testMustRewrite() throws IOException {
|
||||||
|
QueryShardContext context = createShardContext();
|
||||||
|
context.setAllowUnmappedFields(true);
|
||||||
|
TermQueryBuilder queryBuilder = new TermQueryBuilder("unmapped_field", "foo");
|
||||||
|
IllegalStateException e = expectThrows(IllegalStateException.class,
|
||||||
|
() -> queryBuilder.toQuery(context));
|
||||||
|
assertEquals("Rewrite first", e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,16 +112,13 @@ public class TermsQueryBuilderTests extends AbstractQueryTestCase<TermsQueryBuil
|
||||||
protected void doAssertLuceneQuery(TermsQueryBuilder queryBuilder, Query query, QueryShardContext context) throws IOException {
|
protected void doAssertLuceneQuery(TermsQueryBuilder queryBuilder, Query query, QueryShardContext context) throws IOException {
|
||||||
if (queryBuilder.termsLookup() == null && (queryBuilder.values() == null || queryBuilder.values().isEmpty())) {
|
if (queryBuilder.termsLookup() == null && (queryBuilder.values() == null || queryBuilder.values().isEmpty())) {
|
||||||
assertThat(query, instanceOf(MatchNoDocsQuery.class));
|
assertThat(query, instanceOf(MatchNoDocsQuery.class));
|
||||||
MatchNoDocsQuery matchNoDocsQuery = (MatchNoDocsQuery) query;
|
|
||||||
assertThat(matchNoDocsQuery.toString(), containsString("No terms supplied for \"terms\" query."));
|
|
||||||
} else if (queryBuilder.termsLookup() != null && randomTerms.size() == 0){
|
} else if (queryBuilder.termsLookup() != null && randomTerms.size() == 0){
|
||||||
assertThat(query, instanceOf(MatchNoDocsQuery.class));
|
assertThat(query, instanceOf(MatchNoDocsQuery.class));
|
||||||
MatchNoDocsQuery matchNoDocsQuery = (MatchNoDocsQuery) query;
|
|
||||||
assertThat(matchNoDocsQuery.toString(), containsString("No terms supplied for \"terms\" query."));
|
|
||||||
} else {
|
} else {
|
||||||
assertThat(query, either(instanceOf(TermInSetQuery.class))
|
assertThat(query, either(instanceOf(TermInSetQuery.class))
|
||||||
.or(instanceOf(PointInSetQuery.class))
|
.or(instanceOf(PointInSetQuery.class))
|
||||||
.or(instanceOf(ConstantScoreQuery.class)));
|
.or(instanceOf(ConstantScoreQuery.class))
|
||||||
|
.or(instanceOf(MatchNoDocsQuery.class)));
|
||||||
if (query instanceof ConstantScoreQuery) {
|
if (query instanceof ConstantScoreQuery) {
|
||||||
assertThat(((ConstantScoreQuery) query).getQuery(), instanceOf(BooleanQuery.class));
|
assertThat(((ConstantScoreQuery) query).getQuery(), instanceOf(BooleanQuery.class));
|
||||||
}
|
}
|
||||||
|
@ -141,8 +138,13 @@ public class TermsQueryBuilderTests extends AbstractQueryTestCase<TermsQueryBuil
|
||||||
}
|
}
|
||||||
|
|
||||||
String fieldName = expectedFieldName(queryBuilder.fieldName());
|
String fieldName = expectedFieldName(queryBuilder.fieldName());
|
||||||
TermInSetQuery expected = new TermInSetQuery(fieldName,
|
Query expected;
|
||||||
terms.stream().filter(Objects::nonNull).map(Object::toString).map(BytesRef::new).collect(Collectors.toList()));
|
if (context.fieldMapper(fieldName) != null) {
|
||||||
|
expected = new TermInSetQuery(fieldName,
|
||||||
|
terms.stream().filter(Objects::nonNull).map(Object::toString).map(BytesRef::new).collect(Collectors.toList()));
|
||||||
|
} else {
|
||||||
|
expected = new MatchNoDocsQuery();
|
||||||
|
}
|
||||||
assertEquals(expected, query);
|
assertEquals(expected, query);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -267,8 +269,16 @@ public class TermsQueryBuilderTests extends AbstractQueryTestCase<TermsQueryBuil
|
||||||
UnsupportedOperationException e = expectThrows(UnsupportedOperationException.class,
|
UnsupportedOperationException e = expectThrows(UnsupportedOperationException.class,
|
||||||
() -> termsQueryBuilder.toQuery(createShardContext()));
|
() -> termsQueryBuilder.toQuery(createShardContext()));
|
||||||
assertEquals("query must be rewritten first", e.getMessage());
|
assertEquals("query must be rewritten first", e.getMessage());
|
||||||
assertEquals(rewriteAndFetch(termsQueryBuilder, createShardContext()), new TermsQueryBuilder(STRING_FIELD_NAME,
|
|
||||||
randomTerms.stream().filter(x -> x != null).collect(Collectors.toList()))); // terms lookup removes null values
|
// terms lookup removes null values
|
||||||
|
List<Object> nonNullTerms = randomTerms.stream().filter(x -> x != null).collect(Collectors.toList());
|
||||||
|
QueryBuilder expected;
|
||||||
|
if (nonNullTerms.isEmpty()) {
|
||||||
|
expected = new MatchNoneQueryBuilder();
|
||||||
|
} else {
|
||||||
|
expected = new TermsQueryBuilder(STRING_FIELD_NAME, nonNullTerms);
|
||||||
|
}
|
||||||
|
assertEquals(expected, rewriteAndFetch(termsQueryBuilder, createShardContext()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testGeo() throws Exception {
|
public void testGeo() throws Exception {
|
||||||
|
@ -329,7 +339,7 @@ public class TermsQueryBuilderTests extends AbstractQueryTestCase<TermsQueryBuil
|
||||||
TermsQueryBuilder query = new TermsQueryBuilder("_index", "does_not_exist", getIndex().getName());
|
TermsQueryBuilder query = new TermsQueryBuilder("_index", "does_not_exist", getIndex().getName());
|
||||||
QueryShardContext queryShardContext = createShardContext();
|
QueryShardContext queryShardContext = createShardContext();
|
||||||
QueryBuilder rewritten = query.rewrite(queryShardContext);
|
QueryBuilder rewritten = query.rewrite(queryShardContext);
|
||||||
assertThat(rewritten, instanceOf(TermsQueryBuilder.class));
|
assertThat(rewritten, instanceOf(MatchAllQueryBuilder.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -343,4 +353,5 @@ public class TermsQueryBuilderTests extends AbstractQueryTestCase<TermsQueryBuil
|
||||||
}
|
}
|
||||||
return query;
|
return query;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -152,6 +152,16 @@ public class WildcardQueryBuilderTests extends AbstractQueryTestCase<WildcardQue
|
||||||
WildcardQueryBuilder query = new WildcardQueryBuilder("_index", firstHalfOfIndexName +"*");
|
WildcardQueryBuilder query = new WildcardQueryBuilder("_index", firstHalfOfIndexName +"*");
|
||||||
QueryShardContext queryShardContext = createShardContext();
|
QueryShardContext queryShardContext = createShardContext();
|
||||||
QueryBuilder rewritten = query.rewrite(queryShardContext);
|
QueryBuilder rewritten = query.rewrite(queryShardContext);
|
||||||
assertThat(rewritten, instanceOf(WildcardQueryBuilder.class));
|
assertThat(rewritten, instanceOf(MatchAllQueryBuilder.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void testMustRewrite() throws IOException {
|
||||||
|
QueryShardContext context = createShardContext();
|
||||||
|
context.setAllowUnmappedFields(true);
|
||||||
|
WildcardQueryBuilder queryBuilder = new WildcardQueryBuilder("unmapped_field", "foo");
|
||||||
|
IllegalStateException e = expectThrows(IllegalStateException.class,
|
||||||
|
() -> queryBuilder.toQuery(context));
|
||||||
|
assertEquals("Rewrite first", e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -119,7 +119,7 @@ public class WrapperQueryBuilderTests extends AbstractQueryTestCase<WrapperQuery
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void testMustRewrite() throws IOException {
|
public void testMustRewrite() throws IOException {
|
||||||
TermQueryBuilder tqb = new TermQueryBuilder("foo", "bar");
|
TermQueryBuilder tqb = new TermQueryBuilder(STRING_FIELD_NAME, "bar");
|
||||||
WrapperQueryBuilder qb = new WrapperQueryBuilder(tqb.toString());
|
WrapperQueryBuilder qb = new WrapperQueryBuilder(tqb.toString());
|
||||||
UnsupportedOperationException e = expectThrows(UnsupportedOperationException.class, () -> qb.toQuery(createShardContext()));
|
UnsupportedOperationException e = expectThrows(UnsupportedOperationException.class, () -> qb.toQuery(createShardContext()));
|
||||||
assertEquals("this query must be rewritten first", e.getMessage());
|
assertEquals("this query must be rewritten first", e.getMessage());
|
||||||
|
@ -137,7 +137,7 @@ public class WrapperQueryBuilderTests extends AbstractQueryTestCase<WrapperQuery
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testRewriteWithInnerBoost() throws IOException {
|
public void testRewriteWithInnerBoost() throws IOException {
|
||||||
final TermQueryBuilder query = new TermQueryBuilder("foo", "bar").boost(2);
|
final TermQueryBuilder query = new TermQueryBuilder(STRING_FIELD_NAME, "bar").boost(2);
|
||||||
QueryBuilder builder = new WrapperQueryBuilder(query.toString());
|
QueryBuilder builder = new WrapperQueryBuilder(query.toString());
|
||||||
QueryShardContext shardContext = createShardContext();
|
QueryShardContext shardContext = createShardContext();
|
||||||
assertEquals(query, builder.rewrite(shardContext));
|
assertEquals(query, builder.rewrite(shardContext));
|
||||||
|
@ -149,15 +149,15 @@ public class WrapperQueryBuilderTests extends AbstractQueryTestCase<WrapperQuery
|
||||||
QueryShardContext shardContext = createShardContext();
|
QueryShardContext shardContext = createShardContext();
|
||||||
|
|
||||||
QueryBuilder qb = new WrapperQueryBuilder(
|
QueryBuilder qb = new WrapperQueryBuilder(
|
||||||
new WrapperQueryBuilder(new TermQueryBuilder("foo", "bar").toString()).toString()
|
new WrapperQueryBuilder(new TermQueryBuilder(STRING_FIELD_NAME, "bar").toString()).toString()
|
||||||
);
|
);
|
||||||
assertEquals(new TermQuery(new Term("foo", "bar")), qb.rewrite(shardContext).toQuery(shardContext));
|
assertEquals(new TermQuery(new Term(STRING_FIELD_NAME, "bar")), qb.rewrite(shardContext).toQuery(shardContext));
|
||||||
qb = new WrapperQueryBuilder(
|
qb = new WrapperQueryBuilder(
|
||||||
new WrapperQueryBuilder(
|
new WrapperQueryBuilder(
|
||||||
new WrapperQueryBuilder(new TermQueryBuilder("foo", "bar").toString()).toString()
|
new WrapperQueryBuilder(new TermQueryBuilder(STRING_FIELD_NAME, "bar").toString()).toString()
|
||||||
).toString()
|
).toString()
|
||||||
);
|
);
|
||||||
assertEquals(new TermQuery(new Term("foo", "bar")), qb.rewrite(shardContext).toQuery(shardContext));
|
assertEquals(new TermQuery(new Term(STRING_FIELD_NAME, "bar")), qb.rewrite(shardContext).toQuery(shardContext));
|
||||||
|
|
||||||
qb = new WrapperQueryBuilder(new BoolQueryBuilder().toString());
|
qb = new WrapperQueryBuilder(new BoolQueryBuilder().toString());
|
||||||
assertEquals(new MatchAllDocsQuery(), qb.rewrite(shardContext).toQuery(shardContext));
|
assertEquals(new MatchAllDocsQuery(), qb.rewrite(shardContext).toQuery(shardContext));
|
||||||
|
|
|
@ -552,11 +552,12 @@ public class FunctionScoreQueryBuilderTests extends AbstractQueryTestCase<Functi
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testCustomWeightFactorQueryBuilderWithFunctionScore() throws IOException {
|
public void testCustomWeightFactorQueryBuilderWithFunctionScore() throws IOException {
|
||||||
Query parsedQuery = parseQuery(functionScoreQuery(termQuery("name.last", "banon"), weightFactorFunction(1.3f)))
|
QueryShardContext context = createShardContext();
|
||||||
.toQuery(createShardContext());
|
Query parsedQuery = parseQuery(functionScoreQuery(termQuery(STRING_FIELD_NAME_2, "banon"), weightFactorFunction(1.3f)))
|
||||||
|
.rewrite(context).toQuery(context);
|
||||||
assertThat(parsedQuery, instanceOf(FunctionScoreQuery.class));
|
assertThat(parsedQuery, instanceOf(FunctionScoreQuery.class));
|
||||||
FunctionScoreQuery functionScoreQuery = (FunctionScoreQuery) parsedQuery;
|
FunctionScoreQuery functionScoreQuery = (FunctionScoreQuery) parsedQuery;
|
||||||
assertThat(((TermQuery) functionScoreQuery.getSubQuery()).getTerm(), equalTo(new Term("name.last", "banon")));
|
assertThat(((TermQuery) functionScoreQuery.getSubQuery()).getTerm(), equalTo(new Term(STRING_FIELD_NAME_2, "banon")));
|
||||||
assertThat((double) (functionScoreQuery.getFunctions()[0]).getWeight(), closeTo(1.3, 0.001));
|
assertThat((double) (functionScoreQuery.getFunctions()[0]).getWeight(), closeTo(1.3, 0.001));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -642,14 +643,14 @@ public class FunctionScoreQueryBuilderTests extends AbstractQueryTestCase<Functi
|
||||||
|
|
||||||
public void testRewrite() throws IOException {
|
public void testRewrite() throws IOException {
|
||||||
FunctionScoreQueryBuilder functionScoreQueryBuilder =
|
FunctionScoreQueryBuilder functionScoreQueryBuilder =
|
||||||
new FunctionScoreQueryBuilder(new WrapperQueryBuilder(new TermQueryBuilder("foo", "bar").toString()))
|
new FunctionScoreQueryBuilder(new WrapperQueryBuilder(new TermQueryBuilder(STRING_FIELD_NAME, "bar").toString()))
|
||||||
.boostMode(CombineFunction.REPLACE)
|
.boostMode(CombineFunction.REPLACE)
|
||||||
.scoreMode(FunctionScoreQuery.ScoreMode.SUM)
|
.scoreMode(FunctionScoreQuery.ScoreMode.SUM)
|
||||||
.setMinScore(1)
|
.setMinScore(1)
|
||||||
.maxBoost(100);
|
.maxBoost(100);
|
||||||
FunctionScoreQueryBuilder rewrite = (FunctionScoreQueryBuilder) functionScoreQueryBuilder.rewrite(createShardContext());
|
FunctionScoreQueryBuilder rewrite = (FunctionScoreQueryBuilder) functionScoreQueryBuilder.rewrite(createShardContext());
|
||||||
assertNotSame(functionScoreQueryBuilder, rewrite);
|
assertNotSame(functionScoreQueryBuilder, rewrite);
|
||||||
assertEquals(rewrite.query(), new TermQueryBuilder("foo", "bar"));
|
assertEquals(rewrite.query(), new TermQueryBuilder(STRING_FIELD_NAME, "bar"));
|
||||||
assertEquals(rewrite.boostMode(), CombineFunction.REPLACE);
|
assertEquals(rewrite.boostMode(), CombineFunction.REPLACE);
|
||||||
assertEquals(rewrite.scoreMode(), FunctionScoreQuery.ScoreMode.SUM);
|
assertEquals(rewrite.scoreMode(), FunctionScoreQuery.ScoreMode.SUM);
|
||||||
assertEquals(rewrite.getMinScore(), 1f, 0.0001);
|
assertEquals(rewrite.getMinScore(), 1f, 0.0001);
|
||||||
|
@ -657,18 +658,18 @@ public class FunctionScoreQueryBuilderTests extends AbstractQueryTestCase<Functi
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testRewriteWithFunction() throws IOException {
|
public void testRewriteWithFunction() throws IOException {
|
||||||
QueryBuilder firstFunction = new WrapperQueryBuilder(new TermQueryBuilder("tq", "1").toString());
|
QueryBuilder firstFunction = new WrapperQueryBuilder(new TermQueryBuilder(STRING_FIELD_NAME_2, "1").toString());
|
||||||
TermQueryBuilder secondFunction = new TermQueryBuilder("tq", "2");
|
TermQueryBuilder secondFunction = new TermQueryBuilder(STRING_FIELD_NAME_2, "2");
|
||||||
QueryBuilder queryBuilder = randomBoolean() ? new WrapperQueryBuilder(new TermQueryBuilder("foo", "bar").toString())
|
QueryBuilder queryBuilder = randomBoolean() ? new WrapperQueryBuilder(new TermQueryBuilder(STRING_FIELD_NAME, "bar").toString())
|
||||||
: new TermQueryBuilder("foo", "bar");
|
: new TermQueryBuilder(STRING_FIELD_NAME, "bar");
|
||||||
FunctionScoreQueryBuilder functionScoreQueryBuilder = new FunctionScoreQueryBuilder(queryBuilder,
|
FunctionScoreQueryBuilder functionScoreQueryBuilder = new FunctionScoreQueryBuilder(queryBuilder,
|
||||||
new FunctionScoreQueryBuilder.FilterFunctionBuilder[] {
|
new FunctionScoreQueryBuilder.FilterFunctionBuilder[] {
|
||||||
new FunctionScoreQueryBuilder.FilterFunctionBuilder(firstFunction, new RandomScoreFunctionBuilder()),
|
new FunctionScoreQueryBuilder.FilterFunctionBuilder(firstFunction, new RandomScoreFunctionBuilder()),
|
||||||
new FunctionScoreQueryBuilder.FilterFunctionBuilder(secondFunction, new RandomScoreFunctionBuilder()) });
|
new FunctionScoreQueryBuilder.FilterFunctionBuilder(secondFunction, new RandomScoreFunctionBuilder()) });
|
||||||
FunctionScoreQueryBuilder rewrite = (FunctionScoreQueryBuilder) functionScoreQueryBuilder.rewrite(createShardContext());
|
FunctionScoreQueryBuilder rewrite = (FunctionScoreQueryBuilder) functionScoreQueryBuilder.rewrite(createShardContext());
|
||||||
assertNotSame(functionScoreQueryBuilder, rewrite);
|
assertNotSame(functionScoreQueryBuilder, rewrite);
|
||||||
assertEquals(rewrite.query(), new TermQueryBuilder("foo", "bar"));
|
assertEquals(rewrite.query(), new TermQueryBuilder(STRING_FIELD_NAME, "bar"));
|
||||||
assertEquals(rewrite.filterFunctionBuilders()[0].getFilter(), new TermQueryBuilder("tq", "1"));
|
assertEquals(rewrite.filterFunctionBuilders()[0].getFilter(), new TermQueryBuilder(STRING_FIELD_NAME_2, "1"));
|
||||||
assertSame(rewrite.filterFunctionBuilders()[1].getFilter(), secondFunction);
|
assertSame(rewrite.filterFunctionBuilders()[1].getFilter(), secondFunction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -685,7 +686,8 @@ public class FunctionScoreQueryBuilderTests extends AbstractQueryTestCase<Functi
|
||||||
builder.boostMode(randomFrom(CombineFunction.values()));
|
builder.boostMode(randomFrom(CombineFunction.values()));
|
||||||
}
|
}
|
||||||
|
|
||||||
Query query = builder.toQuery(createShardContext());
|
QueryShardContext shardContext = createShardContext();
|
||||||
|
Query query = builder.rewrite(shardContext).toQuery(shardContext);
|
||||||
assertThat(query, instanceOf(FunctionScoreQuery.class));
|
assertThat(query, instanceOf(FunctionScoreQuery.class));
|
||||||
|
|
||||||
CombineFunction expectedBoostMode = builder.boostMode() != null
|
CombineFunction expectedBoostMode = builder.boostMode() != null
|
||||||
|
@ -840,4 +842,27 @@ public class FunctionScoreQueryBuilderTests extends AbstractQueryTestCase<Functi
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void testMustRewrite() throws IOException {
|
||||||
|
QueryShardContext context = createShardContext();
|
||||||
|
context.setAllowUnmappedFields(true);
|
||||||
|
TermQueryBuilder termQueryBuilder = new TermQueryBuilder("unmapped_field", "foo");
|
||||||
|
|
||||||
|
// main query needs rewriting
|
||||||
|
FunctionScoreQueryBuilder functionQueryBuilder1 = new FunctionScoreQueryBuilder(termQueryBuilder);
|
||||||
|
functionQueryBuilder1.setMinScore(1);
|
||||||
|
IllegalStateException e = expectThrows(IllegalStateException.class,
|
||||||
|
() -> functionQueryBuilder1.toQuery(context));
|
||||||
|
assertEquals("Rewrite first", e.getMessage());
|
||||||
|
|
||||||
|
// filter needs rewriting
|
||||||
|
FunctionScoreQueryBuilder functionQueryBuilder2 = new FunctionScoreQueryBuilder(new MatchAllQueryBuilder(),
|
||||||
|
new FilterFunctionBuilder[] {
|
||||||
|
new FilterFunctionBuilder(termQueryBuilder, new RandomScoreFunctionBuilder())
|
||||||
|
});
|
||||||
|
e = expectThrows(IllegalStateException.class,
|
||||||
|
() -> functionQueryBuilder2.toQuery(context));
|
||||||
|
assertEquals("Rewrite first", e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -683,13 +683,15 @@ public class TermsAggregatorTests extends AggregatorTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (multiValued == false) {
|
if (multiValued == false) {
|
||||||
|
MappedFieldType filterFieldType = new KeywordFieldMapper.KeywordFieldType();
|
||||||
|
filterFieldType.setName("include");
|
||||||
aggregationBuilder = new FilterAggregationBuilder("_name1", QueryBuilders.termQuery("include", "yes"));
|
aggregationBuilder = new FilterAggregationBuilder("_name1", QueryBuilders.termQuery("include", "yes"));
|
||||||
aggregationBuilder.subAggregation(new TermsAggregationBuilder("_name2", valueType)
|
aggregationBuilder.subAggregation(new TermsAggregationBuilder("_name2", valueType)
|
||||||
.executionHint(executionHint)
|
.executionHint(executionHint)
|
||||||
.size(numTerms)
|
.size(numTerms)
|
||||||
.collectMode(randomFrom(Aggregator.SubAggCollectionMode.values()))
|
.collectMode(randomFrom(Aggregator.SubAggCollectionMode.values()))
|
||||||
.field("field"));
|
.field("field"));
|
||||||
aggregator = createAggregator(aggregationBuilder, indexSearcher, fieldType);
|
aggregator = createAggregator(aggregationBuilder, indexSearcher, fieldType, filterFieldType);
|
||||||
aggregator.preCollection();
|
aggregator.preCollection();
|
||||||
indexSearcher.search(new MatchAllDocsQuery(), aggregator);
|
indexSearcher.search(new MatchAllDocsQuery(), aggregator);
|
||||||
aggregator.postCollection();
|
aggregator.postCollection();
|
||||||
|
|
|
@ -291,6 +291,7 @@ public class HighlightBuilderTests extends ESTestCase {
|
||||||
|
|
||||||
for (int runs = 0; runs < NUMBER_OF_TESTBUILDERS; runs++) {
|
for (int runs = 0; runs < NUMBER_OF_TESTBUILDERS; runs++) {
|
||||||
HighlightBuilder highlightBuilder = randomHighlighterBuilder();
|
HighlightBuilder highlightBuilder = randomHighlighterBuilder();
|
||||||
|
highlightBuilder = Rewriteable.rewrite(highlightBuilder, mockShardContext);
|
||||||
SearchContextHighlight highlight = highlightBuilder.build(mockShardContext);
|
SearchContextHighlight highlight = highlightBuilder.build(mockShardContext);
|
||||||
for (SearchContextHighlight.Field field : highlight.fields()) {
|
for (SearchContextHighlight.Field field : highlight.fields()) {
|
||||||
String encoder = highlightBuilder.encoder() != null ? highlightBuilder.encoder() : HighlightBuilder.DEFAULT_ENCODER;
|
String encoder = highlightBuilder.encoder() != null ? highlightBuilder.encoder() : HighlightBuilder.DEFAULT_ENCODER;
|
||||||
|
|
|
@ -48,6 +48,7 @@ import org.elasticsearch.index.query.IdsQueryBuilder;
|
||||||
import org.elasticsearch.index.query.MatchAllQueryBuilder;
|
import org.elasticsearch.index.query.MatchAllQueryBuilder;
|
||||||
import org.elasticsearch.index.query.QueryBuilder;
|
import org.elasticsearch.index.query.QueryBuilder;
|
||||||
import org.elasticsearch.index.query.QueryShardContext;
|
import org.elasticsearch.index.query.QueryShardContext;
|
||||||
|
import org.elasticsearch.index.query.Rewriteable;
|
||||||
import org.elasticsearch.index.query.TermQueryBuilder;
|
import org.elasticsearch.index.query.TermQueryBuilder;
|
||||||
import org.elasticsearch.script.MockScriptEngine;
|
import org.elasticsearch.script.MockScriptEngine;
|
||||||
import org.elasticsearch.script.ScriptEngine;
|
import org.elasticsearch.script.ScriptEngine;
|
||||||
|
@ -154,7 +155,8 @@ public abstract class AbstractSortTestCase<T extends SortBuilder<T>> extends EST
|
||||||
QueryShardContext mockShardContext = createMockShardContext();
|
QueryShardContext mockShardContext = createMockShardContext();
|
||||||
for (int runs = 0; runs < NUMBER_OF_TESTBUILDERS; runs++) {
|
for (int runs = 0; runs < NUMBER_OF_TESTBUILDERS; runs++) {
|
||||||
T sortBuilder = createTestItem();
|
T sortBuilder = createTestItem();
|
||||||
SortFieldAndFormat sortField = sortBuilder.build(mockShardContext);
|
SortFieldAndFormat sortField = Rewriteable.rewrite(sortBuilder, mockShardContext)
|
||||||
|
.build(mockShardContext);
|
||||||
sortFieldAssertions(sortBuilder, sortField.field, sortField.format);
|
sortFieldAssertions(sortBuilder, sortField.field, sortField.format);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -166,7 +166,9 @@ public abstract class AggregatorTestCase extends ESTestCase {
|
||||||
MappedFieldType... fieldTypes) throws IOException {
|
MappedFieldType... fieldTypes) throws IOException {
|
||||||
SearchContext searchContext = createSearchContext(indexSearcher, indexSettings, query, bucketConsumer, fieldTypes);
|
SearchContext searchContext = createSearchContext(indexSearcher, indexSettings, query, bucketConsumer, fieldTypes);
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
A aggregator = (A) aggregationBuilder.build(searchContext.getQueryShardContext(), null)
|
A aggregator = (A) aggregationBuilder
|
||||||
|
.rewrite(searchContext.getQueryShardContext())
|
||||||
|
.build(searchContext.getQueryShardContext(), null)
|
||||||
.create(searchContext, null, true);
|
.create(searchContext, null, true);
|
||||||
return aggregator;
|
return aggregator;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ package org.elasticsearch.test;
|
||||||
import com.fasterxml.jackson.core.io.JsonStringEncoder;
|
import com.fasterxml.jackson.core.io.JsonStringEncoder;
|
||||||
|
|
||||||
import org.apache.lucene.search.BoostQuery;
|
import org.apache.lucene.search.BoostQuery;
|
||||||
|
import org.apache.lucene.search.MatchNoDocsQuery;
|
||||||
import org.apache.lucene.search.Query;
|
import org.apache.lucene.search.Query;
|
||||||
import org.apache.lucene.search.TermQuery;
|
import org.apache.lucene.search.TermQuery;
|
||||||
import org.apache.lucene.search.spans.SpanBoostQuery;
|
import org.apache.lucene.search.spans.SpanBoostQuery;
|
||||||
|
@ -453,7 +454,7 @@ public abstract class AbstractQueryTestCase<QB extends AbstractQueryBuilder<QB>>
|
||||||
rewrite(secondLuceneQuery), rewrite(firstLuceneQuery));
|
rewrite(secondLuceneQuery), rewrite(firstLuceneQuery));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (supportsBoost()) {
|
if (supportsBoost() && firstLuceneQuery instanceof MatchNoDocsQuery == false) {
|
||||||
secondQuery.boost(firstQuery.boost() + 1f + randomFloat());
|
secondQuery.boost(firstQuery.boost() + 1f + randomFloat());
|
||||||
Query thirdLuceneQuery = rewriteQuery(secondQuery, context).toQuery(context);
|
Query thirdLuceneQuery = rewriteQuery(secondQuery, context).toQuery(context);
|
||||||
assertNotEquals("modifying the boost doesn't affect the corresponding lucene query", rewrite(firstLuceneQuery),
|
assertNotEquals("modifying the boost doesn't affect the corresponding lucene query", rewrite(firstLuceneQuery),
|
||||||
|
@ -495,20 +496,23 @@ public abstract class AbstractQueryTestCase<QB extends AbstractQueryBuilder<QB>>
|
||||||
* {@link #doAssertLuceneQuery(AbstractQueryBuilder, Query, QueryShardContext)} for query specific checks.
|
* {@link #doAssertLuceneQuery(AbstractQueryBuilder, Query, QueryShardContext)} for query specific checks.
|
||||||
*/
|
*/
|
||||||
private void assertLuceneQuery(QB queryBuilder, Query query, QueryShardContext context) throws IOException {
|
private void assertLuceneQuery(QB queryBuilder, Query query, QueryShardContext context) throws IOException {
|
||||||
if (queryBuilder.queryName() != null) {
|
if (queryBuilder.queryName() != null && query instanceof MatchNoDocsQuery == false) {
|
||||||
Query namedQuery = context.copyNamedQueries().get(queryBuilder.queryName());
|
Query namedQuery = context.copyNamedQueries().get(queryBuilder.queryName());
|
||||||
assertThat(namedQuery, equalTo(query));
|
assertThat(namedQuery, equalTo(query));
|
||||||
}
|
}
|
||||||
if (query != null) {
|
if (query != null) {
|
||||||
if (queryBuilder.boost() != AbstractQueryBuilder.DEFAULT_BOOST) {
|
if (queryBuilder.boost() != AbstractQueryBuilder.DEFAULT_BOOST) {
|
||||||
assertThat(query, either(instanceOf(BoostQuery.class)).or(instanceOf(SpanBoostQuery.class)));
|
assertThat(query, either(instanceOf(BoostQuery.class)).or(instanceOf(SpanBoostQuery.class))
|
||||||
|
.or(instanceOf(MatchNoDocsQuery.class)));
|
||||||
if (query instanceof SpanBoostQuery) {
|
if (query instanceof SpanBoostQuery) {
|
||||||
SpanBoostQuery spanBoostQuery = (SpanBoostQuery) query;
|
SpanBoostQuery spanBoostQuery = (SpanBoostQuery) query;
|
||||||
assertThat(spanBoostQuery.getBoost(), equalTo(queryBuilder.boost()));
|
assertThat(spanBoostQuery.getBoost(), equalTo(queryBuilder.boost()));
|
||||||
query = spanBoostQuery.getQuery();
|
query = spanBoostQuery.getQuery();
|
||||||
} else {
|
} else if (query instanceof BoostQuery) {
|
||||||
BoostQuery boostQuery = (BoostQuery) query;
|
BoostQuery boostQuery = (BoostQuery) query;
|
||||||
assertThat(boostQuery.getBoost(), equalTo(queryBuilder.boost()));
|
if (boostQuery.getQuery() instanceof MatchNoDocsQuery == false) {
|
||||||
|
assertThat(boostQuery.getBoost(), equalTo(queryBuilder.boost()));
|
||||||
|
}
|
||||||
query = boostQuery.getQuery();
|
query = boostQuery.getQuery();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ import org.elasticsearch.common.logging.Loggers;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.util.BigArrays;
|
import org.elasticsearch.common.util.BigArrays;
|
||||||
import org.elasticsearch.index.IndexSettings;
|
import org.elasticsearch.index.IndexSettings;
|
||||||
|
import org.elasticsearch.index.mapper.KeywordFieldMapper;
|
||||||
import org.elasticsearch.index.mapper.MapperService;
|
import org.elasticsearch.index.mapper.MapperService;
|
||||||
import org.elasticsearch.index.query.QueryBuilders;
|
import org.elasticsearch.index.query.QueryBuilders;
|
||||||
import org.elasticsearch.index.query.QueryShardContext;
|
import org.elasticsearch.index.query.QueryShardContext;
|
||||||
|
@ -68,6 +69,7 @@ import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
public class DocumentSubsetBitsetCacheTests extends ESTestCase {
|
public class DocumentSubsetBitsetCacheTests extends ESTestCase {
|
||||||
|
|
||||||
|
private static final String MISSING_FIELD_NAME = "does-not-exist";
|
||||||
private static final int FIELD_COUNT = 10;
|
private static final int FIELD_COUNT = 10;
|
||||||
private ExecutorService singleThreadExecutor;
|
private ExecutorService singleThreadExecutor;
|
||||||
|
|
||||||
|
@ -99,7 +101,7 @@ public class DocumentSubsetBitsetCacheTests extends ESTestCase {
|
||||||
public void testNullBitSetIsReturnedForNonMatchingQuery() throws Exception {
|
public void testNullBitSetIsReturnedForNonMatchingQuery() throws Exception {
|
||||||
final DocumentSubsetBitsetCache cache = newCache(Settings.EMPTY);
|
final DocumentSubsetBitsetCache cache = newCache(Settings.EMPTY);
|
||||||
runTestOnIndex((shardContext, leafContext) -> {
|
runTestOnIndex((shardContext, leafContext) -> {
|
||||||
final Query query = QueryBuilders.termQuery("does-not-exist", "any-value").toQuery(shardContext);
|
final Query query = QueryBuilders.termQuery(MISSING_FIELD_NAME, "any-value").rewrite(shardContext).toQuery(shardContext);
|
||||||
final BitSet bitSet = cache.getBitSet(query, leafContext);
|
final BitSet bitSet = cache.getBitSet(query, leafContext);
|
||||||
assertThat(bitSet, nullValue());
|
assertThat(bitSet, nullValue());
|
||||||
});
|
});
|
||||||
|
@ -543,6 +545,17 @@ public class DocumentSubsetBitsetCacheTests extends ESTestCase {
|
||||||
|
|
||||||
private void runTestOnIndices(int numberIndices, CheckedConsumer<List<TestIndexContext>, Exception> body) throws Exception {
|
private void runTestOnIndices(int numberIndices, CheckedConsumer<List<TestIndexContext>, Exception> body) throws Exception {
|
||||||
final MapperService mapperService = mock(MapperService.class);
|
final MapperService mapperService = mock(MapperService.class);
|
||||||
|
when(mapperService.fieldType(Mockito.anyString())).thenAnswer(invocation -> {
|
||||||
|
final String fieldName = (String) invocation.getArguments()[0];
|
||||||
|
if (fieldName.equals(MISSING_FIELD_NAME)) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
KeywordFieldMapper.KeywordFieldType ft = new KeywordFieldMapper.KeywordFieldType();
|
||||||
|
ft.setName(fieldName);
|
||||||
|
ft.freeze();
|
||||||
|
return ft;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
final Client client = mock(Client.class);
|
final Client client = mock(Client.class);
|
||||||
when(client.settings()).thenReturn(Settings.EMPTY);
|
when(client.settings()).thenReturn(Settings.EMPTY);
|
||||||
|
|
|
@ -29,12 +29,14 @@ import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.util.BigArrays;
|
import org.elasticsearch.common.util.BigArrays;
|
||||||
import org.elasticsearch.common.util.concurrent.ThreadContext;
|
import org.elasticsearch.common.util.concurrent.ThreadContext;
|
||||||
import org.elasticsearch.index.IndexSettings;
|
import org.elasticsearch.index.IndexSettings;
|
||||||
|
import org.elasticsearch.index.mapper.KeywordFieldMapper;
|
||||||
import org.elasticsearch.index.mapper.MapperService;
|
import org.elasticsearch.index.mapper.MapperService;
|
||||||
import org.elasticsearch.index.query.ParsedQuery;
|
import org.elasticsearch.index.query.ParsedQuery;
|
||||||
import org.elasticsearch.index.query.QueryShardContext;
|
import org.elasticsearch.index.query.QueryShardContext;
|
||||||
import org.elasticsearch.index.query.TermsQueryBuilder;
|
import org.elasticsearch.index.query.TermsQueryBuilder;
|
||||||
import org.elasticsearch.index.shard.ShardId;
|
import org.elasticsearch.index.shard.ShardId;
|
||||||
import org.elasticsearch.license.XPackLicenseState;
|
import org.elasticsearch.license.XPackLicenseState;
|
||||||
|
import org.elasticsearch.mock.orig.Mockito;
|
||||||
import org.elasticsearch.script.ScriptService;
|
import org.elasticsearch.script.ScriptService;
|
||||||
import org.elasticsearch.search.internal.ContextIndexSearcher;
|
import org.elasticsearch.search.internal.ContextIndexSearcher;
|
||||||
import org.elasticsearch.test.AbstractBuilderTestCase;
|
import org.elasticsearch.test.AbstractBuilderTestCase;
|
||||||
|
@ -69,6 +71,13 @@ public class SecurityIndexReaderWrapperIntegrationTests extends AbstractBuilderT
|
||||||
when(mapperService.documentMapper()).thenReturn(null);
|
when(mapperService.documentMapper()).thenReturn(null);
|
||||||
when(mapperService.simpleMatchToFullName(anyString()))
|
when(mapperService.simpleMatchToFullName(anyString()))
|
||||||
.then(invocationOnMock -> Collections.singletonList((String) invocationOnMock.getArguments()[0]));
|
.then(invocationOnMock -> Collections.singletonList((String) invocationOnMock.getArguments()[0]));
|
||||||
|
when(mapperService.fieldType(Mockito.anyString())).then(invocation -> {
|
||||||
|
final String fieldName = (String) invocation.getArguments()[0];
|
||||||
|
KeywordFieldMapper.KeywordFieldType ft = new KeywordFieldMapper.KeywordFieldType();
|
||||||
|
ft.setName(fieldName);
|
||||||
|
ft.freeze();
|
||||||
|
return ft;
|
||||||
|
});
|
||||||
|
|
||||||
final ThreadContext threadContext = new ThreadContext(Settings.EMPTY);
|
final ThreadContext threadContext = new ThreadContext(Settings.EMPTY);
|
||||||
final SecurityContext securityContext = new SecurityContext(Settings.EMPTY, threadContext);
|
final SecurityContext securityContext = new SecurityContext(Settings.EMPTY, threadContext);
|
||||||
|
@ -177,6 +186,13 @@ public class SecurityIndexReaderWrapperIntegrationTests extends AbstractBuilderT
|
||||||
when(mapperService.documentMapper()).thenReturn(null);
|
when(mapperService.documentMapper()).thenReturn(null);
|
||||||
when(mapperService.simpleMatchToFullName(anyString()))
|
when(mapperService.simpleMatchToFullName(anyString()))
|
||||||
.then(invocationOnMock -> Collections.singletonList((String) invocationOnMock.getArguments()[0]));
|
.then(invocationOnMock -> Collections.singletonList((String) invocationOnMock.getArguments()[0]));
|
||||||
|
when(mapperService.fieldType(Mockito.anyString())).then(invocation -> {
|
||||||
|
final String fieldName = (String) invocation.getArguments()[0];
|
||||||
|
KeywordFieldMapper.KeywordFieldType ft = new KeywordFieldMapper.KeywordFieldType();
|
||||||
|
ft.setName(fieldName);
|
||||||
|
ft.freeze();
|
||||||
|
return ft;
|
||||||
|
});
|
||||||
|
|
||||||
final ThreadContext threadContext = new ThreadContext(Settings.EMPTY);
|
final ThreadContext threadContext = new ThreadContext(Settings.EMPTY);
|
||||||
final SecurityContext securityContext = new SecurityContext(Settings.EMPTY, threadContext);
|
final SecurityContext securityContext = new SecurityContext(Settings.EMPTY, threadContext);
|
||||||
|
@ -203,7 +219,8 @@ public class SecurityIndexReaderWrapperIntegrationTests extends AbstractBuilderT
|
||||||
IndicesAccessControl.IndexAccessControl limitedIndexAccessControl = new IndicesAccessControl.IndexAccessControl(true, new
|
IndicesAccessControl.IndexAccessControl limitedIndexAccessControl = new IndicesAccessControl.IndexAccessControl(true, new
|
||||||
FieldPermissions(),
|
FieldPermissions(),
|
||||||
DocumentPermissions.filteredBy(queries));
|
DocumentPermissions.filteredBy(queries));
|
||||||
IndexSettings indexSettings = IndexSettingsModule.newIndexSettings(shardId.getIndex(), Settings.EMPTY);
|
IndexSettings indexSettings = IndexSettingsModule.newIndexSettings(shardId.getIndex(),
|
||||||
|
Settings.builder().put(IndexSettings.ALLOW_UNMAPPED.getKey(), false).build());
|
||||||
Client client = mock(Client.class);
|
Client client = mock(Client.class);
|
||||||
when(client.settings()).thenReturn(Settings.EMPTY);
|
when(client.settings()).thenReturn(Settings.EMPTY);
|
||||||
final long nowInMillis = randomNonNegativeLong();
|
final long nowInMillis = randomNonNegativeLong();
|
||||||
|
|
|
@ -170,4 +170,13 @@ public class PinnedQueryBuilderTests extends AbstractQueryTestCase<PinnedQueryBu
|
||||||
assertThat(rewritten, instanceOf(PinnedQueryBuilder.class));
|
assertThat(rewritten, instanceOf(PinnedQueryBuilder.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void testMustRewrite() throws IOException {
|
||||||
|
QueryShardContext context = createShardContext();
|
||||||
|
context.setAllowUnmappedFields(true);
|
||||||
|
PinnedQueryBuilder queryBuilder = new PinnedQueryBuilder(new TermQueryBuilder("unmapped_field", "42"));
|
||||||
|
IllegalStateException e = expectThrows(IllegalStateException.class,
|
||||||
|
() -> queryBuilder.toQuery(context));
|
||||||
|
assertEquals("Rewrite first", e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue