Remove the distinction between query and filter context in QueryBuilders (#35354)
When building a query Lucene distinguishes two cases, queries that require to produce a score and queries that only need to match. We cloned this mechanism in the QueryBuilders in order to be able to produce different queries based on whether they need to produce a score or not. However the only case in es that require this distinction is the BoolQueryBuilder that sets a different minimum_should_match when a `bool` query is built in a filter context.. This behavior doesn't seem right because it makes the matching of `should` clauses different when the score is not required. Closes #35293
This commit is contained in:
parent
328d022ddd
commit
74aca756b8
|
@ -159,3 +159,14 @@ Negative scores in the Function Score Query are deprecated in 6.x, and are
|
|||
not allowed in this version. If a negative score is produced as a result
|
||||
of computation (e.g. in `script_score` or `field_value_factor` functions),
|
||||
an error will be thrown.
|
||||
|
||||
[float]
|
||||
==== The filter context has been removed
|
||||
|
||||
The `filter` context has been removed from Elasticsearch's query builders,
|
||||
the distinction between queries and filters is now decided in Lucene depending
|
||||
on whether queries need to access score or not. As a result `bool` queries with
|
||||
`should` clauses that don't need to access the score will no longer set their
|
||||
`minimum_should_match` to 1. This behavior has been deprecated in the previous
|
||||
major version.
|
||||
|
||||
|
|
|
@ -17,15 +17,7 @@ contribute to the score.
|
|||
in <<query-filter-context,filter context>>, meaning that scoring is ignored
|
||||
and clauses are considered for caching.
|
||||
|
||||
|`should` |The clause (query) should appear in the matching document. If the
|
||||
`bool` query is in a <<query-filter-context,query context>> and has a `must` or
|
||||
`filter` clause then a document will match the `bool` query even if none of the
|
||||
`should` queries match. In this case these clauses are only used to influence
|
||||
the score. If the `bool` query is a <<query-filter-context,filter context>>
|
||||
or has neither `must` or `filter` then at least one of the `should` queries
|
||||
must match a document for it to match the `bool` query. This behavior may be
|
||||
explicitly controlled by settings the
|
||||
<<query-dsl-minimum-should-match,`minimum_should_match`>> parameter.
|
||||
|`should` |The clause (query) should appear in the matching document.
|
||||
|
||||
|`must_not` |The clause (query) must not appear in the matching
|
||||
documents. Clauses are executed in <<query-filter-context,filter context>> meaning
|
||||
|
@ -33,13 +25,6 @@ that scoring is ignored and clauses are considered for caching. Because scoring
|
|||
ignored, a score of `0` for all documents is returned.
|
||||
|=======================================================================
|
||||
|
||||
[IMPORTANT]
|
||||
.Bool query in filter context
|
||||
========================================================================
|
||||
If this query is used in a filter context and it has `should`
|
||||
clauses then at least one `should` clause is required to match.
|
||||
========================================================================
|
||||
|
||||
The `bool` query takes a _more-matches-is-better_ approach, so the score from
|
||||
each matching `must` or `should` clause will be added together to provide the
|
||||
final `_score` for each document.
|
||||
|
|
|
@ -139,6 +139,6 @@ public class AliasValidator {
|
|||
private static void validateAliasFilter(XContentParser parser, QueryShardContext queryShardContext) throws IOException {
|
||||
QueryBuilder parseInnerQueryBuilder = parseInnerQueryBuilder(parser);
|
||||
QueryBuilder queryBuilder = Rewriteable.rewrite(parseInnerQueryBuilder, queryShardContext, true);
|
||||
queryBuilder.toFilter(queryShardContext);
|
||||
queryBuilder.toQuery(queryShardContext);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -111,19 +111,6 @@ public abstract class AbstractQueryBuilder<QB extends AbstractQueryBuilder<QB>>
|
|||
return query;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Query toFilter(QueryShardContext context) throws IOException {
|
||||
Query result;
|
||||
final boolean originalIsFilter = context.isFilter();
|
||||
try {
|
||||
context.setIsFilter(true);
|
||||
result = toQuery(context);
|
||||
} finally {
|
||||
context.setIsFilter(originalIsFilter);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
protected abstract Query doToQuery(QueryShardContext context) throws IOException;
|
||||
|
||||
/**
|
||||
|
|
|
@ -384,12 +384,6 @@ public class BoolQueryBuilder extends AbstractQueryBuilder<BoolQueryBuilder> {
|
|||
return new MatchAllDocsQuery();
|
||||
}
|
||||
|
||||
final String minimumShouldMatch;
|
||||
if (context.isFilter() && this.minimumShouldMatch == null && shouldClauses.size() > 0) {
|
||||
minimumShouldMatch = "1";
|
||||
} else {
|
||||
minimumShouldMatch = this.minimumShouldMatch;
|
||||
}
|
||||
Query query = Queries.applyMinimumShouldMatch(booleanQuery, minimumShouldMatch);
|
||||
return adjustPureNegative ? fixNegativeQueryIfNeeded(query) : query;
|
||||
}
|
||||
|
@ -397,17 +391,7 @@ public class BoolQueryBuilder extends AbstractQueryBuilder<BoolQueryBuilder> {
|
|||
private static void addBooleanClauses(QueryShardContext context, BooleanQuery.Builder booleanQueryBuilder,
|
||||
List<QueryBuilder> clauses, Occur occurs) throws IOException {
|
||||
for (QueryBuilder query : clauses) {
|
||||
Query luceneQuery = null;
|
||||
switch (occurs) {
|
||||
case MUST:
|
||||
case SHOULD:
|
||||
luceneQuery = query.toQuery(context);
|
||||
break;
|
||||
case FILTER:
|
||||
case MUST_NOT:
|
||||
luceneQuery = query.toFilter(context);
|
||||
break;
|
||||
}
|
||||
Query luceneQuery = query.toQuery(context);
|
||||
booleanQueryBuilder.add(new BooleanClause(luceneQuery, occurs));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -129,7 +129,7 @@ public class ConstantScoreQueryBuilder extends AbstractQueryBuilder<ConstantScor
|
|||
|
||||
@Override
|
||||
protected Query doToQuery(QueryShardContext context) throws IOException {
|
||||
Query innerFilter = filterBuilder.toFilter(context);
|
||||
Query innerFilter = filterBuilder.toQuery(context);
|
||||
return new ConstantScoreQuery(innerFilter);
|
||||
}
|
||||
|
||||
|
|
|
@ -326,9 +326,6 @@ public class FuzzyQueryBuilder extends AbstractQueryBuilder<FuzzyQueryBuilder> i
|
|||
protected Query doToQuery(QueryShardContext context) throws IOException {
|
||||
Query query = null;
|
||||
String rewrite = this.rewrite;
|
||||
if (rewrite == null && context.isFilter()) {
|
||||
rewrite = QueryParsers.CONSTANT_SCORE.getPreferredName();
|
||||
}
|
||||
MappedFieldType fieldType = context.fieldMapper(fieldName);
|
||||
if (fieldType != null) {
|
||||
query = fieldType.fuzzyQuery(value, fuzziness, prefixLength, maxExpansions, transpositions);
|
||||
|
|
|
@ -37,16 +37,6 @@ public interface QueryBuilder extends NamedWriteable, ToXContentObject, Rewritea
|
|||
*/
|
||||
Query toQuery(QueryShardContext context) throws IOException;
|
||||
|
||||
/**
|
||||
* Converts this QueryBuilder to an unscored lucene {@link Query} that acts as a filter.
|
||||
* Returns {@code null} if this query should be ignored in the context of
|
||||
* parent queries.
|
||||
*
|
||||
* @param context additional information needed to construct the queries
|
||||
* @return the {@link Query} or {@code null} if this query should be ignored upstream
|
||||
*/
|
||||
Query toFilter(QueryShardContext context) throws IOException;
|
||||
|
||||
/**
|
||||
* Sets the arbitrary name to be assigned to the query (see named queries).
|
||||
* Implementers should return the concrete type of the
|
||||
|
|
|
@ -97,7 +97,6 @@ public class QueryShardContext extends QueryRewriteContext {
|
|||
private boolean allowUnmappedFields;
|
||||
private boolean mapUnmappedFieldAsString;
|
||||
private NestedScope nestedScope;
|
||||
private boolean isFilter;
|
||||
|
||||
public QueryShardContext(int shardId, IndexSettings indexSettings, BitsetFilterCache bitsetFilterCache,
|
||||
BiFunction<MappedFieldType, String, IndexFieldData<?>> indexFieldDataLookup, MapperService mapperService,
|
||||
|
@ -132,7 +131,6 @@ public class QueryShardContext extends QueryRewriteContext {
|
|||
this.lookup = null;
|
||||
this.namedQueries.clear();
|
||||
this.nestedScope = new NestedScope();
|
||||
this.isFilter = false;
|
||||
}
|
||||
|
||||
public IndexAnalyzers getIndexAnalyzers() {
|
||||
|
@ -178,22 +176,6 @@ public class QueryShardContext extends QueryRewriteContext {
|
|||
return unmodifiableMap(new HashMap<>(namedQueries));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether we are currently parsing a filter or a query.
|
||||
*/
|
||||
public boolean isFilter() {
|
||||
return isFilter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Public for testing only!
|
||||
*
|
||||
* Sets whether we are currently parsing a filter or a query
|
||||
*/
|
||||
public void setIsFilter(boolean isFilter) {
|
||||
this.isFilter = isFilter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all the fields that match a given pattern. If prefixed with a
|
||||
* type then the fields will be returned with a type prefix.
|
||||
|
@ -289,16 +271,6 @@ public class QueryShardContext extends QueryRewriteContext {
|
|||
return indexSettings.getIndexVersionCreated();
|
||||
}
|
||||
|
||||
public ParsedQuery toFilter(QueryBuilder queryBuilder) {
|
||||
return toQuery(queryBuilder, q -> {
|
||||
Query filter = q.toFilter(this);
|
||||
if (filter == null) {
|
||||
return null;
|
||||
}
|
||||
return filter;
|
||||
});
|
||||
}
|
||||
|
||||
public ParsedQuery toQuery(QueryBuilder queryBuilder) {
|
||||
return toQuery(queryBuilder, q -> {
|
||||
Query query = q.toQuery(this);
|
||||
|
|
|
@ -346,11 +346,6 @@ public class SpanNearQueryBuilder extends AbstractQueryBuilder<SpanNearQueryBuil
|
|||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Query toFilter(QueryShardContext context) throws IOException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String queryName() {
|
||||
throw new UnsupportedOperationException();
|
||||
|
|
|
@ -244,7 +244,7 @@ final class DefaultSearchContext extends SearchContext {
|
|||
// initialize the filtering alias based on the provided filters
|
||||
try {
|
||||
final QueryBuilder queryBuilder = request.getAliasFilter().getQueryBuilder();
|
||||
aliasFilter = queryBuilder == null ? null : queryBuilder.toFilter(queryShardContext);
|
||||
aliasFilter = queryBuilder == null ? null : queryBuilder.toQuery(queryShardContext);
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ public class AdjacencyMatrixAggregatorFactory extends AggregatorFactory<Adjacenc
|
|||
for (int i = 0; i < filters.size(); ++i) {
|
||||
KeyedFilter keyedFilter = filters.get(i);
|
||||
this.keys[i] = keyedFilter.key();
|
||||
Query filter = keyedFilter.filter().toFilter(context.getQueryShardContext());
|
||||
Query filter = keyedFilter.filter().toQuery(context.getQueryShardContext());
|
||||
this.weights[i] = contextSearcher.createWeight(contextSearcher.rewrite(filter), ScoreMode.COMPLETE_NO_SCORES, 1f);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ public class FilterAggregatorFactory extends AggregatorFactory<FilterAggregatorF
|
|||
public FilterAggregatorFactory(String name, QueryBuilder filterBuilder, SearchContext context,
|
||||
AggregatorFactory<?> parent, AggregatorFactories.Builder subFactoriesBuilder, Map<String, Object> metaData) throws IOException {
|
||||
super(name, context, parent, subFactoriesBuilder, metaData);
|
||||
filter = filterBuilder.toFilter(context.getQueryShardContext());
|
||||
filter = filterBuilder.toQuery(context.getQueryShardContext());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -56,7 +56,7 @@ public class FiltersAggregatorFactory extends AggregatorFactory<FiltersAggregato
|
|||
for (int i = 0; i < filters.size(); ++i) {
|
||||
KeyedFilter keyedFilter = filters.get(i);
|
||||
this.keys[i] = keyedFilter.key();
|
||||
this.filters[i] = keyedFilter.filter().toFilter(context.getQueryShardContext());
|
||||
this.filters[i] = keyedFilter.filter().toQuery(context.getQueryShardContext());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -96,7 +96,7 @@ public class SignificantTermsAggregatorFactory extends ValuesSourceAggregatorFac
|
|||
this.executionHint = executionHint;
|
||||
this.filter = filterBuilder == null
|
||||
? null
|
||||
: filterBuilder.toFilter(context.getQueryShardContext());
|
||||
: filterBuilder.toQuery(context.getQueryShardContext());
|
||||
IndexSearcher searcher = context.searcher();
|
||||
this.supersetNumDocs = filter == null
|
||||
// Important - need to use the doc count that includes deleted docs
|
||||
|
|
|
@ -226,9 +226,9 @@ public abstract class SortBuilder<T extends SortBuilder<T>> implements NamedWrit
|
|||
assert nestedFilter == Rewriteable.rewrite(nestedFilter, context) : "nested filter is not rewritten";
|
||||
if (parentQuery == null) {
|
||||
// this is for back-compat, original single level nested sorting never applied a nested type filter
|
||||
childQuery = nestedFilter.toFilter(context);
|
||||
childQuery = nestedFilter.toQuery(context);
|
||||
} else {
|
||||
childQuery = Queries.filtered(nestedObjectMapper.nestedTypeFilter(), nestedFilter.toFilter(context));
|
||||
childQuery = Queries.filtered(nestedObjectMapper.nestedTypeFilter(), nestedFilter.toQuery(context));
|
||||
}
|
||||
} else {
|
||||
childQuery = nestedObjectMapper.nestedTypeFilter();
|
||||
|
|
|
@ -21,7 +21,6 @@ package org.elasticsearch.index.query;
|
|||
|
||||
import org.apache.lucene.search.BooleanClause;
|
||||
import org.apache.lucene.search.BooleanQuery;
|
||||
import org.apache.lucene.search.ConstantScoreQuery;
|
||||
import org.apache.lucene.search.MatchAllDocsQuery;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.elasticsearch.common.ParsingException;
|
||||
|
@ -41,7 +40,6 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
|
||||
import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
|
||||
import static org.elasticsearch.index.query.QueryBuilders.constantScoreQuery;
|
||||
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||
|
@ -176,26 +174,6 @@ public class BoolQueryBuilderTests extends AbstractQueryTestCase<BoolQueryBuilde
|
|||
}
|
||||
}
|
||||
|
||||
public void testDefaultMinShouldMatch() throws Exception {
|
||||
// Queries have a minShouldMatch of 0
|
||||
BooleanQuery bq = (BooleanQuery) parseQuery(boolQuery().must(termQuery("foo", "bar"))).toQuery(createShardContext());
|
||||
assertEquals(0, bq.getMinimumNumberShouldMatch());
|
||||
|
||||
bq = (BooleanQuery) parseQuery(boolQuery().should(termQuery("foo", "bar"))).toQuery(createShardContext());
|
||||
assertEquals(0, bq.getMinimumNumberShouldMatch());
|
||||
|
||||
// Filters have a minShouldMatch of 0/1
|
||||
ConstantScoreQuery csq = (ConstantScoreQuery) parseQuery(constantScoreQuery(boolQuery()
|
||||
.must(termQuery("foo", "bar")))).toQuery(createShardContext());
|
||||
bq = (BooleanQuery) csq.getQuery();
|
||||
assertEquals(0, bq.getMinimumNumberShouldMatch());
|
||||
|
||||
csq = (ConstantScoreQuery) parseQuery(constantScoreQuery(boolQuery().should(termQuery("foo", "bar"))))
|
||||
.toQuery(createShardContext());
|
||||
bq = (BooleanQuery) csq.getQuery();
|
||||
assertEquals(1, bq.getMinimumNumberShouldMatch());
|
||||
}
|
||||
|
||||
public void testMinShouldMatchFilterWithoutShouldClauses() throws Exception {
|
||||
BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
|
||||
boolQueryBuilder.filter(new BoolQueryBuilder().must(new MatchAllQueryBuilder()));
|
||||
|
@ -216,29 +194,6 @@ public class BoolQueryBuilderTests extends AbstractQueryTestCase<BoolQueryBuilde
|
|||
assertThat(innerBooleanClause.getQuery(), instanceOf(MatchAllDocsQuery.class));
|
||||
}
|
||||
|
||||
public void testMinShouldMatchFilterWithShouldClauses() throws Exception {
|
||||
BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
|
||||
boolQueryBuilder.filter(new BoolQueryBuilder().must(new MatchAllQueryBuilder()).should(new MatchAllQueryBuilder()));
|
||||
Query query = boolQueryBuilder.toQuery(createShardContext());
|
||||
assertThat(query, instanceOf(BooleanQuery.class));
|
||||
BooleanQuery booleanQuery = (BooleanQuery) query;
|
||||
assertThat(booleanQuery.getMinimumNumberShouldMatch(), equalTo(0));
|
||||
assertThat(booleanQuery.clauses().size(), equalTo(1));
|
||||
BooleanClause booleanClause = booleanQuery.clauses().get(0);
|
||||
assertThat(booleanClause.getOccur(), equalTo(BooleanClause.Occur.FILTER));
|
||||
assertThat(booleanClause.getQuery(), instanceOf(BooleanQuery.class));
|
||||
BooleanQuery innerBooleanQuery = (BooleanQuery) booleanClause.getQuery();
|
||||
//we didn't set minimum should match initially, but there are should clauses so it should be 1
|
||||
assertThat(innerBooleanQuery.getMinimumNumberShouldMatch(), equalTo(1));
|
||||
assertThat(innerBooleanQuery.clauses().size(), equalTo(2));
|
||||
BooleanClause innerBooleanClause1 = innerBooleanQuery.clauses().get(0);
|
||||
assertThat(innerBooleanClause1.getOccur(), equalTo(BooleanClause.Occur.MUST));
|
||||
assertThat(innerBooleanClause1.getQuery(), instanceOf(MatchAllDocsQuery.class));
|
||||
BooleanClause innerBooleanClause2 = innerBooleanQuery.clauses().get(1);
|
||||
assertThat(innerBooleanClause2.getOccur(), equalTo(BooleanClause.Occur.SHOULD));
|
||||
assertThat(innerBooleanClause2.getQuery(), instanceOf(MatchAllDocsQuery.class));
|
||||
}
|
||||
|
||||
public void testMinShouldMatchBiggerThanNumberOfShouldClauses() throws Exception {
|
||||
BooleanQuery bq = (BooleanQuery) parseQuery(
|
||||
boolQuery()
|
||||
|
|
|
@ -114,11 +114,6 @@ public class SpanMultiTermQueryBuilderTests extends AbstractQueryTestCase<SpanMu
|
|||
return new TermQuery(new Term("foo", "bar"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Query toFilter(QueryShardContext context) throws IOException {
|
||||
return toQuery(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueryBuilder queryName(String queryName) {
|
||||
return this;
|
||||
|
|
|
@ -19,10 +19,6 @@
|
|||
|
||||
package org.elasticsearch.index.query.plugin;
|
||||
|
||||
import org.apache.lucene.search.BooleanClause;
|
||||
import org.apache.lucene.search.BooleanQuery;
|
||||
import org.apache.lucene.search.ConstantScoreQuery;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.elasticsearch.index.query.BoolQueryBuilder;
|
||||
import org.elasticsearch.index.query.QueryShardContext;
|
||||
import org.elasticsearch.indices.IndicesService;
|
||||
|
@ -33,10 +29,7 @@ import org.junit.Before;
|
|||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
|
||||
import static org.elasticsearch.index.query.QueryBuilders.constantScoreQuery;
|
||||
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCount;
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
|
||||
public class CustomQueryParserIT extends ESIntegTestCase {
|
||||
@Override
|
||||
|
@ -77,65 +70,4 @@ public class CustomQueryParserIT extends ESIntegTestCase {
|
|||
return indicesService.indexServiceSafe(resolveIndex("index")).newQueryShardContext(
|
||||
randomInt(20), null, () -> { throw new UnsupportedOperationException(); }, null);
|
||||
}
|
||||
|
||||
//see #11120
|
||||
public void testConstantScoreParsesFilter() throws Exception {
|
||||
Query q = constantScoreQuery(new DummyQueryBuilder()).toQuery(queryShardContext());
|
||||
Query inner = ((ConstantScoreQuery) q).getQuery();
|
||||
assertThat(inner, instanceOf(DummyQueryParserPlugin.DummyQuery.class));
|
||||
assertEquals(true, ((DummyQueryParserPlugin.DummyQuery) inner).isFilter);
|
||||
}
|
||||
|
||||
//see #11120
|
||||
public void testBooleanParsesFilter() throws Exception {
|
||||
// single clause, serialized as inner object
|
||||
Query q = boolQuery()
|
||||
.should(new DummyQueryBuilder())
|
||||
.must(new DummyQueryBuilder())
|
||||
.filter(new DummyQueryBuilder())
|
||||
.mustNot(new DummyQueryBuilder()).toQuery(queryShardContext());
|
||||
assertThat(q, instanceOf(BooleanQuery.class));
|
||||
BooleanQuery bq = (BooleanQuery) q;
|
||||
assertEquals(4, bq.clauses().size());
|
||||
for (BooleanClause clause : bq.clauses()) {
|
||||
DummyQueryParserPlugin.DummyQuery dummy = (DummyQueryParserPlugin.DummyQuery) clause.getQuery();
|
||||
switch (clause.getOccur()) {
|
||||
case FILTER:
|
||||
case MUST_NOT:
|
||||
assertEquals(true, dummy.isFilter);
|
||||
break;
|
||||
case MUST:
|
||||
case SHOULD:
|
||||
assertEquals(false, dummy.isFilter);
|
||||
break;
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
|
||||
// multiple clauses, serialized as inner arrays
|
||||
q = boolQuery()
|
||||
.should(new DummyQueryBuilder()).should(new DummyQueryBuilder())
|
||||
.must(new DummyQueryBuilder()).must(new DummyQueryBuilder())
|
||||
.filter(new DummyQueryBuilder()).filter(new DummyQueryBuilder())
|
||||
.mustNot(new DummyQueryBuilder()).mustNot(new DummyQueryBuilder()).toQuery(queryShardContext());
|
||||
assertThat(q, instanceOf(BooleanQuery.class));
|
||||
bq = (BooleanQuery) q;
|
||||
assertEquals(8, bq.clauses().size());
|
||||
for (BooleanClause clause : bq.clauses()) {
|
||||
DummyQueryParserPlugin.DummyQuery dummy = (DummyQueryParserPlugin.DummyQuery) clause.getQuery();
|
||||
switch (clause.getOccur()) {
|
||||
case FILTER:
|
||||
case MUST_NOT:
|
||||
assertEquals(true, dummy.isFilter);
|
||||
break;
|
||||
case MUST:
|
||||
case SHOULD:
|
||||
assertEquals(false, dummy.isFilter);
|
||||
break;
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ public class DummyQueryBuilder extends AbstractQueryBuilder<DummyQueryBuilder> {
|
|||
|
||||
@Override
|
||||
protected Query doToQuery(QueryShardContext context) throws IOException {
|
||||
return new DummyQuery(context.isFilter());
|
||||
return new DummyQuery();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -40,13 +40,8 @@ public class DummyQueryParserPlugin extends Plugin implements SearchPlugin {
|
|||
}
|
||||
|
||||
public static class DummyQuery extends Query {
|
||||
public final boolean isFilter;
|
||||
private final Query matchAllDocsQuery = new MatchAllDocsQuery();
|
||||
|
||||
public DummyQuery(boolean isFilter) {
|
||||
this.isFilter = isFilter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(String field) {
|
||||
return getClass().getSimpleName();
|
||||
|
|
|
@ -23,24 +23,17 @@ import org.apache.lucene.document.Field;
|
|||
import org.apache.lucene.index.DirectoryReader;
|
||||
import org.apache.lucene.index.IndexOptions;
|
||||
import org.apache.lucene.index.IndexReader;
|
||||
import org.apache.lucene.index.MultiReader;
|
||||
import org.apache.lucene.index.RandomIndexWriter;
|
||||
import org.apache.lucene.search.BooleanQuery;
|
||||
import org.apache.lucene.search.IndexSearcher;
|
||||
import org.apache.lucene.search.MatchAllDocsQuery;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.apache.lucene.store.Directory;
|
||||
import org.elasticsearch.index.mapper.KeywordFieldMapper;
|
||||
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||
import org.elasticsearch.index.query.QueryBuilder;
|
||||
import org.elasticsearch.index.query.QueryBuilders;
|
||||
import org.elasticsearch.search.aggregations.AggregatorFactory;
|
||||
import org.elasticsearch.search.aggregations.AggregatorTestCase;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.Before;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class FilterAggregatorTests extends AggregatorTestCase {
|
||||
private MappedFieldType fieldType;
|
||||
|
||||
|
@ -107,22 +100,4 @@ public class FilterAggregatorTests extends AggregatorTestCase {
|
|||
indexReader.close();
|
||||
directory.close();
|
||||
}
|
||||
|
||||
public void testParsedAsFilter() throws IOException {
|
||||
IndexReader indexReader = new MultiReader();
|
||||
IndexSearcher indexSearcher = newSearcher(indexReader);
|
||||
QueryBuilder filter = QueryBuilders.boolQuery()
|
||||
.must(QueryBuilders.termQuery("field", "foo"))
|
||||
.should(QueryBuilders.termQuery("field", "bar"));
|
||||
FilterAggregationBuilder builder = new FilterAggregationBuilder("test", filter);
|
||||
AggregatorFactory<?> factory = createAggregatorFactory(builder, indexSearcher, fieldType);
|
||||
assertThat(factory, Matchers.instanceOf(FilterAggregatorFactory.class));
|
||||
FilterAggregatorFactory filterFactory = (FilterAggregatorFactory) factory;
|
||||
Query parsedQuery = filterFactory.getWeight().getQuery();
|
||||
assertThat(parsedQuery, Matchers.instanceOf(BooleanQuery.class));
|
||||
assertEquals(2, ((BooleanQuery) parsedQuery).clauses().size());
|
||||
// means the bool query has been parsed as a filter, if it was a query minShouldMatch would
|
||||
// be 0
|
||||
assertEquals(1, ((BooleanQuery) parsedQuery).getMinimumNumberShouldMatch());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,23 +23,17 @@ import org.apache.lucene.document.Field;
|
|||
import org.apache.lucene.index.DirectoryReader;
|
||||
import org.apache.lucene.index.IndexOptions;
|
||||
import org.apache.lucene.index.IndexReader;
|
||||
import org.apache.lucene.index.MultiReader;
|
||||
import org.apache.lucene.index.RandomIndexWriter;
|
||||
import org.apache.lucene.search.BooleanQuery;
|
||||
import org.apache.lucene.search.IndexSearcher;
|
||||
import org.apache.lucene.search.MatchAllDocsQuery;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.apache.lucene.store.Directory;
|
||||
import org.elasticsearch.index.mapper.KeywordFieldMapper;
|
||||
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||
import org.elasticsearch.index.query.QueryBuilder;
|
||||
import org.elasticsearch.index.query.QueryBuilders;
|
||||
import org.elasticsearch.search.aggregations.AggregatorFactory;
|
||||
import org.elasticsearch.search.aggregations.AggregatorTestCase;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.Before;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
@ -203,22 +197,4 @@ public class FiltersAggregatorTests extends AggregatorTestCase {
|
|||
indexReader.close();
|
||||
directory.close();
|
||||
}
|
||||
|
||||
public void testParsedAsFilter() throws IOException {
|
||||
IndexReader indexReader = new MultiReader();
|
||||
IndexSearcher indexSearcher = newSearcher(indexReader);
|
||||
QueryBuilder filter = QueryBuilders.boolQuery()
|
||||
.must(QueryBuilders.termQuery("field", "foo"))
|
||||
.should(QueryBuilders.termQuery("field", "bar"));
|
||||
FiltersAggregationBuilder builder = new FiltersAggregationBuilder("test", filter);
|
||||
AggregatorFactory<?> factory = createAggregatorFactory(builder, indexSearcher, fieldType);
|
||||
assertThat(factory, Matchers.instanceOf(FiltersAggregatorFactory.class));
|
||||
FiltersAggregatorFactory filtersFactory = (FiltersAggregatorFactory) factory;
|
||||
Query parsedQuery = filtersFactory.getWeights()[0].getQuery();
|
||||
assertThat(parsedQuery, Matchers.instanceOf(BooleanQuery.class));
|
||||
assertEquals(2, ((BooleanQuery) parsedQuery).clauses().size());
|
||||
// means the bool query has been parsed as a filter, if it was a query minShouldMatch would
|
||||
// be 0
|
||||
assertEquals(1, ((BooleanQuery) parsedQuery).getMinimumNumberShouldMatch());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,11 +28,8 @@ import org.apache.lucene.index.IndexOptions;
|
|||
import org.apache.lucene.index.IndexReader;
|
||||
import org.apache.lucene.index.IndexWriter;
|
||||
import org.apache.lucene.index.IndexWriterConfig;
|
||||
import org.apache.lucene.index.MultiReader;
|
||||
import org.apache.lucene.index.Term;
|
||||
import org.apache.lucene.search.BooleanQuery;
|
||||
import org.apache.lucene.search.IndexSearcher;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.apache.lucene.search.TermQuery;
|
||||
import org.apache.lucene.store.Directory;
|
||||
import org.apache.lucene.util.BytesRef;
|
||||
|
@ -46,12 +43,9 @@ import org.elasticsearch.index.mapper.NumberFieldMapper.NumberType;
|
|||
import org.elasticsearch.index.mapper.TextFieldMapper.TextFieldType;
|
||||
import org.elasticsearch.index.query.QueryBuilder;
|
||||
import org.elasticsearch.index.query.QueryBuilders;
|
||||
import org.elasticsearch.search.aggregations.AggregatorFactory;
|
||||
import org.elasticsearch.search.aggregations.AggregatorTestCase;
|
||||
import org.elasticsearch.search.aggregations.bucket.significant.SignificantTermsAggregatorFactory.ExecutionMode;
|
||||
import org.elasticsearch.search.aggregations.bucket.terms.IncludeExclude;
|
||||
import org.elasticsearch.search.aggregations.support.ValueType;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.Before;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -86,28 +80,6 @@ public class SignificantTermsAggregatorTests extends AggregatorTestCase {
|
|||
Function.identity()));
|
||||
}
|
||||
|
||||
public void testParsedAsFilter() throws IOException {
|
||||
IndexReader indexReader = new MultiReader();
|
||||
IndexSearcher indexSearcher = newSearcher(indexReader);
|
||||
QueryBuilder filter = QueryBuilders.boolQuery()
|
||||
.must(QueryBuilders.termQuery("field", "foo"))
|
||||
.should(QueryBuilders.termQuery("field", "bar"));
|
||||
SignificantTermsAggregationBuilder builder = new SignificantTermsAggregationBuilder(
|
||||
"test", ValueType.STRING)
|
||||
.field("field")
|
||||
.backgroundFilter(filter);
|
||||
AggregatorFactory<?> factory = createAggregatorFactory(builder, indexSearcher, fieldType);
|
||||
assertThat(factory, Matchers.instanceOf(SignificantTermsAggregatorFactory.class));
|
||||
SignificantTermsAggregatorFactory sigTermsFactory =
|
||||
(SignificantTermsAggregatorFactory) factory;
|
||||
Query parsedQuery = sigTermsFactory.filter;
|
||||
assertThat(parsedQuery, Matchers.instanceOf(BooleanQuery.class));
|
||||
assertEquals(2, ((BooleanQuery) parsedQuery).clauses().size());
|
||||
// means the bool query has been parsed as a filter, if it was a query minShouldMatch would
|
||||
// be 0
|
||||
assertEquals(1, ((BooleanQuery) parsedQuery).getMinimumNumberShouldMatch());
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses the significant terms aggregation to find the keywords in text fields
|
||||
*/
|
||||
|
|
|
@ -76,7 +76,6 @@ import org.elasticsearch.search.lookup.SearchLookup;
|
|||
import org.elasticsearch.test.ESTestCase;
|
||||
import org.elasticsearch.test.InternalAggregationTestCase;
|
||||
import org.junit.After;
|
||||
import org.mockito.Matchers;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
@ -306,8 +305,6 @@ public abstract class AggregatorTestCase extends ESTestCase {
|
|||
QueryShardContext queryShardContext = mock(QueryShardContext.class);
|
||||
when(queryShardContext.getMapperService()).thenReturn(mapperService);
|
||||
NestedScope nestedScope = new NestedScope();
|
||||
when(queryShardContext.isFilter()).thenCallRealMethod();
|
||||
Mockito.doCallRealMethod().when(queryShardContext).setIsFilter(Matchers.anyBoolean());
|
||||
when(queryShardContext.nestedScope()).thenReturn(nestedScope);
|
||||
return queryShardContext;
|
||||
}
|
||||
|
|
|
@ -466,12 +466,6 @@ public abstract class AbstractQueryTestCase<QB extends AbstractQueryBuilder<QB>>
|
|||
assertNotEquals("modifying the boost doesn't affect the corresponding lucene query", rewrite(firstLuceneQuery),
|
||||
rewrite(thirdLuceneQuery));
|
||||
}
|
||||
|
||||
// check that context#isFilter is not changed by invoking toQuery/rewrite
|
||||
boolean filterFlag = randomBoolean();
|
||||
context.setIsFilter(filterFlag);
|
||||
rewriteQuery(firstQuery, context).toQuery(context);
|
||||
assertEquals("isFilter should be unchanged", filterFlag, context.isFilter());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -136,7 +136,7 @@ public class SecurityIndexSearcherWrapper extends IndexSearcherWrapper {
|
|||
QueryBuilder queryBuilder = queryShardContext.parseInnerQueryBuilder(parser);
|
||||
verifyRoleQuery(queryBuilder);
|
||||
failIfQueryUsesClient(queryBuilder, queryShardContext);
|
||||
Query roleQuery = queryShardContext.toFilter(queryBuilder).query();
|
||||
Query roleQuery = queryShardContext.toQuery(queryBuilder).query();
|
||||
filter.add(roleQuery, SHOULD);
|
||||
if (queryShardContext.getMapperService().hasNested()) {
|
||||
NestedHelper nestedHelper = new NestedHelper(queryShardContext.getMapperService());
|
||||
|
|
|
@ -142,7 +142,7 @@ public class SecurityIndexSearcherWrapperIntegrationTests extends ESTestCase {
|
|||
for (int i = 0; i < numValues; i++) {
|
||||
ParsedQuery parsedQuery = new ParsedQuery(new TermQuery(new Term("field", values[i])));
|
||||
doReturn(new TermQueryBuilder("field", values[i])).when(queryShardContext).parseInnerQueryBuilder(any(XContentParser.class));
|
||||
when(queryShardContext.toFilter(new TermsQueryBuilder("field", values[i]))).thenReturn(parsedQuery);
|
||||
when(queryShardContext.toQuery(new TermsQueryBuilder("field", values[i]))).thenReturn(parsedQuery);
|
||||
DirectoryReader wrappedDirectoryReader = wrapper.wrap(directoryReader);
|
||||
IndexSearcher indexSearcher = wrapper.wrap(new IndexSearcher(wrappedDirectoryReader));
|
||||
|
||||
|
|
Loading…
Reference in New Issue