diff --git a/docs/reference/migration/migrate_2_0.asciidoc b/docs/reference/migration/migrate_2_0.asciidoc index e9c647e406b..744570ef5d3 100644 --- a/docs/reference/migration/migrate_2_0.asciidoc +++ b/docs/reference/migration/migrate_2_0.asciidoc @@ -425,6 +425,38 @@ Change to ranking behaviour: single-term queries on numeric fields now score in Previously, term queries on numeric fields were deliberately prevented from using the usual Lucene scoring logic and this behaviour was undocumented and, to some, unexpected. If the introduction of scoring to numeric fields is undesirable for your query clauses the fix is simple: wrap them in a `constant_score` or use a `filter` expression instead. +The `filtered` query is deprecated. Instead you should use a `bool` query with +a `must` clause for the query and a `filter` clause for the filter. For instance +the below query: + +[source,json] +--------------- +{ + "filtered": { + "query": { + // query + }, + "filter": { + // filter + } + } +} +--------------- +can be replaced with +[source,json] +--------------- +{ + "bool": { + "must": { + // query + }, + "filter": { + // filter + } + } +} +--------------- +and will produce the same scores. The `fuzzy_like_this` and `fuzzy_like_this_field` queries have been removed. diff --git a/docs/reference/query-dsl/bool-query.asciidoc b/docs/reference/query-dsl/bool-query.asciidoc index e6d90cce766..ac6e9f62250 100644 --- a/docs/reference/query-dsl/bool-query.asciidoc +++ b/docs/reference/query-dsl/bool-query.asciidoc @@ -9,7 +9,11 @@ occurrence types are: [cols="<,<",options="header",] |======================================================================= |Occur |Description -|`must` |The clause (query) must appear in matching documents. +|`must` |The clause (query) must appear in matching documents and will +contribute to the score. + +|`filter` |The clause (query) must appear in matching documents. However unlike +`must` the score of the query will be ignored. |`should` |The clause (query) should appear in the matching document. In a boolean query with no `must` clauses, one or more `should` clauses @@ -41,6 +45,9 @@ final `_score` for each document. "must" : { "term" : { "user" : "kimchy" } }, + "filter": { + "term" : { "tag" : "tech" } + } "must_not" : { "range" : { "age" : { "from" : 10, "to" : 20 } diff --git a/docs/reference/query-dsl/filtered-query.asciidoc b/docs/reference/query-dsl/filtered-query.asciidoc index 655cfa804c4..094d3edefc1 100644 --- a/docs/reference/query-dsl/filtered-query.asciidoc +++ b/docs/reference/query-dsl/filtered-query.asciidoc @@ -1,6 +1,8 @@ [[query-dsl-filtered-query]] == Filtered Query +deprecated[2.0.0, Use the `bool` query instead with a `must` clause for the query and a `filter` clause for the filter] + The `filtered` query is used to combine a query which will be used for scoring with another query which will only be used for filtering the result set. diff --git a/src/main/java/org/elasticsearch/index/query/BoolQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/BoolQueryBuilder.java index ca12ff5a927..da5c93fe380 100644 --- a/src/main/java/org/elasticsearch/index/query/BoolQueryBuilder.java +++ b/src/main/java/org/elasticsearch/index/query/BoolQueryBuilder.java @@ -31,11 +31,13 @@ import java.util.List; */ public class BoolQueryBuilder extends BaseQueryBuilder implements BoostableQueryBuilder { - private ArrayList mustClauses = new ArrayList<>(); + private final List mustClauses = new ArrayList<>(); - private ArrayList mustNotClauses = new ArrayList<>(); + private final List mustNotClauses = new ArrayList<>(); - private ArrayList shouldClauses = new ArrayList<>(); + private final List filterClauses = new ArrayList<>(); + + private final List shouldClauses = new ArrayList<>(); private float boost = -1; @@ -48,7 +50,8 @@ public class BoolQueryBuilder extends BaseQueryBuilder implements BoostableQuery private String queryName; /** - * Adds a query that must appear in the matching documents. + * Adds a query that must appear in the matching documents and will + * contribute to scoring. */ public BoolQueryBuilder must(QueryBuilder queryBuilder) { mustClauses.add(queryBuilder); @@ -56,7 +59,17 @@ public class BoolQueryBuilder extends BaseQueryBuilder implements BoostableQuery } /** - * Adds a query that must not appear in the matching documents. + * Adds a query that must appear in the matching documents but will + * not contribute to scoring. + */ + public BoolQueryBuilder filter(QueryBuilder queryBuilder) { + filterClauses.add(queryBuilder); + return this; + } + + /** + * Adds a query that must not appear in the matching documents and + * will not contribute to scoring. */ public BoolQueryBuilder mustNot(QueryBuilder queryBuilder) { mustNotClauses.add(queryBuilder); @@ -149,6 +162,7 @@ public class BoolQueryBuilder extends BaseQueryBuilder implements BoostableQuery protected void doXContent(XContentBuilder builder, Params params) throws IOException { builder.startObject("bool"); doXArrayContent("must", mustClauses, builder, params); + doXArrayContent("filter", filterClauses, builder, params); doXArrayContent("must_not", mustNotClauses, builder, params); doXArrayContent("should", shouldClauses, builder, params); if (boost != -1) { diff --git a/src/main/java/org/elasticsearch/index/query/BoolQueryParser.java b/src/main/java/org/elasticsearch/index/query/BoolQueryParser.java index 25d176c0219..6fa7faa85db 100644 --- a/src/main/java/org/elasticsearch/index/query/BoolQueryParser.java +++ b/src/main/java/org/elasticsearch/index/query/BoolQueryParser.java @@ -71,54 +71,72 @@ public class BoolQueryParser implements QueryParser { } else if (parseContext.isDeprecatedSetting(currentFieldName)) { // skip } else if (token == XContentParser.Token.START_OBJECT) { - if ("must".equals(currentFieldName)) { + switch (currentFieldName) { + case "must": Query query = parseContext.parseInnerQuery(); if (query != null) { clauses.add(new BooleanClause(query, BooleanClause.Occur.MUST)); } - } else if ("must_not".equals(currentFieldName) || "mustNot".equals(currentFieldName)) { - Query query = parseContext.parseInnerFilter(); - if (query != null) { - clauses.add(new BooleanClause(query, BooleanClause.Occur.MUST_NOT)); - } - } else if ("should".equals(currentFieldName)) { - Query query = parseContext.parseInnerQuery(); + break; + case "should": + query = parseContext.parseInnerQuery(); if (query != null) { clauses.add(new BooleanClause(query, BooleanClause.Occur.SHOULD)); if (parseContext.isFilter() && minimumShouldMatch == null) { minimumShouldMatch = "1"; } } - } else { + break; + case "filter": + query = parseContext.parseInnerFilter(); + if (query != null) { + clauses.add(new BooleanClause(query, BooleanClause.Occur.FILTER)); + } + break; + case "must_not": + case "mustNot": + query = parseContext.parseInnerFilter(); + if (query != null) { + clauses.add(new BooleanClause(query, BooleanClause.Occur.MUST_NOT)); + } + break; + default: throw new QueryParsingException(parseContext, "[bool] query does not support [" + currentFieldName + "]"); } } else if (token == XContentParser.Token.START_ARRAY) { - if ("must".equals(currentFieldName)) { - while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) { + while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) { + switch (currentFieldName) { + case "must": Query query = parseContext.parseInnerQuery(); if (query != null) { clauses.add(new BooleanClause(query, BooleanClause.Occur.MUST)); } - } - } else if ("must_not".equals(currentFieldName) || "mustNot".equals(currentFieldName)) { - while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) { - Query query = parseContext.parseInnerFilter(); - if (query != null) { - clauses.add(new BooleanClause(query, BooleanClause.Occur.MUST_NOT)); - } - } - } else if ("should".equals(currentFieldName)) { - while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) { - Query query = parseContext.parseInnerQuery(); + break; + case "should": + query = parseContext.parseInnerQuery(); if (query != null) { clauses.add(new BooleanClause(query, BooleanClause.Occur.SHOULD)); if (parseContext.isFilter() && minimumShouldMatch == null) { minimumShouldMatch = "1"; } } + break; + case "filter": + query = parseContext.parseInnerFilter(); + if (query != null) { + clauses.add(new BooleanClause(query, BooleanClause.Occur.FILTER)); + } + break; + case "must_not": + case "mustNot": + query = parseContext.parseInnerFilter(); + if (query != null) { + clauses.add(new BooleanClause(query, BooleanClause.Occur.MUST_NOT)); + } + break; + default: + throw new QueryParsingException(parseContext, "bool query does not support [" + currentFieldName + "]"); } - } else { - throw new QueryParsingException(parseContext, "bool query does not support [" + currentFieldName + "]"); } } else if (token.isValue()) { if ("disable_coord".equals(currentFieldName) || "disableCoord".equals(currentFieldName)) { diff --git a/src/main/java/org/elasticsearch/index/query/FilteredQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/FilteredQueryBuilder.java index e9c9e960787..9315fd65686 100644 --- a/src/main/java/org/elasticsearch/index/query/FilteredQueryBuilder.java +++ b/src/main/java/org/elasticsearch/index/query/FilteredQueryBuilder.java @@ -26,7 +26,9 @@ import java.io.IOException; /** * A query that applies a filter to the results of another query. + * @deprecated Use {@link BoolQueryBuilder} instead. */ +@Deprecated public class FilteredQueryBuilder extends BaseQueryBuilder implements BoostableQueryBuilder { private final QueryBuilder queryBuilder; diff --git a/src/main/java/org/elasticsearch/index/query/FilteredQueryParser.java b/src/main/java/org/elasticsearch/index/query/FilteredQueryParser.java index 68f270be58e..774ff743ed9 100644 --- a/src/main/java/org/elasticsearch/index/query/FilteredQueryParser.java +++ b/src/main/java/org/elasticsearch/index/query/FilteredQueryParser.java @@ -19,11 +19,10 @@ package org.elasticsearch.index.query; +import org.apache.lucene.search.BooleanClause.Occur; +import org.apache.lucene.search.BooleanQuery; import org.apache.lucene.search.ConstantScoreQuery; -import org.apache.lucene.search.Filter; -import org.apache.lucene.search.FilteredQuery; import org.apache.lucene.search.Query; -import org.apache.lucene.search.QueryWrapperFilter; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.lucene.search.Queries; import org.elasticsearch.common.xcontent.XContentParser; @@ -33,6 +32,7 @@ import java.io.IOException; /** * */ +@Deprecated public class FilteredQueryParser implements QueryParser { public static final String NAME = "filtered"; @@ -58,7 +58,6 @@ public class FilteredQueryParser implements QueryParser { String currentFieldName = null; XContentParser.Token token; - FilteredQuery.FilterStrategy filterStrategy = FilteredQuery.RANDOM_ACCESS_FILTER_STRATEGY; while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { if (token == XContentParser.Token.FIELD_NAME) { @@ -76,24 +75,7 @@ public class FilteredQueryParser implements QueryParser { } } else if (token.isValue()) { if ("strategy".equals(currentFieldName)) { - String value = parser.text(); - if ("query_first".equals(value) || "queryFirst".equals(value)) { - filterStrategy = FilteredQuery.QUERY_FIRST_FILTER_STRATEGY; - } else if ("random_access_always".equals(value) || "randomAccessAlways".equals(value)) { - filterStrategy = FilteredQuery.RANDOM_ACCESS_FILTER_STRATEGY; - } else if ("leap_frog".equals(value) || "leapFrog".equals(value)) { - filterStrategy = FilteredQuery.LEAP_FROG_QUERY_FIRST_STRATEGY; - } else if (value.startsWith("random_access_")) { - filterStrategy = FilteredQuery.RANDOM_ACCESS_FILTER_STRATEGY; - } else if (value.startsWith("randomAccess")) { - filterStrategy = FilteredQuery.RANDOM_ACCESS_FILTER_STRATEGY; - } else if ("leap_frog_query_first".equals(value) || "leapFrogQueryFirst".equals(value)) { - filterStrategy = FilteredQuery.LEAP_FROG_QUERY_FIRST_STRATEGY; - } else if ("leap_frog_filter_first".equals(value) || "leapFrogFilterFirst".equals(value)) { - filterStrategy = FilteredQuery.LEAP_FROG_FILTER_FIRST_STRATEGY; - } else { - throw new QueryParsingException(parseContext, "[filtered] strategy value not supported [" + value + "]"); - } + // ignore } else if ("_name".equals(currentFieldName)) { queryName = parser.text(); } else if ("boost".equals(currentFieldName)) { @@ -131,10 +113,8 @@ public class FilteredQueryParser implements QueryParser { return q; } - if (filter instanceof Filter == false) { - filter = new QueryWrapperFilter(filter); - } - FilteredQuery filteredQuery = new FilteredQuery(query, (Filter) filter, filterStrategy); + BooleanQuery filteredQuery = Queries.filtered(query, filter); + filteredQuery.setBoost(boost); if (queryName != null) { parseContext.addNamedQuery(queryName, filteredQuery); diff --git a/src/main/java/org/elasticsearch/index/query/QueryBuilders.java b/src/main/java/org/elasticsearch/index/query/QueryBuilders.java index 2cfc41769ab..fe2e572522b 100644 --- a/src/main/java/org/elasticsearch/index/query/QueryBuilders.java +++ b/src/main/java/org/elasticsearch/index/query/QueryBuilders.java @@ -355,7 +355,10 @@ public abstract class QueryBuilders { * * @param queryBuilder The query to apply the filter to * @param filterBuilder The filter to apply on the query + * @deprecated Use {@link #boolQuery()} instead with a {@code must} clause + * for the query and a {@code filter} clause for the filter. */ + @Deprecated public static FilteredQueryBuilder filteredQuery(@Nullable QueryBuilder queryBuilder, @Nullable QueryBuilder filterBuilder) { return new FilteredQueryBuilder(queryBuilder, filterBuilder); } diff --git a/src/test/java/org/elasticsearch/index/query/SimpleIndexQueryParserTests.java b/src/test/java/org/elasticsearch/index/query/SimpleIndexQueryParserTests.java index d3ab6b4cbc5..a23f5e312ca 100644 --- a/src/test/java/org/elasticsearch/index/query/SimpleIndexQueryParserTests.java +++ b/src/test/java/org/elasticsearch/index/query/SimpleIndexQueryParserTests.java @@ -37,8 +37,6 @@ import org.apache.lucene.search.BooleanClause.Occur; import org.apache.lucene.search.BooleanQuery; import org.apache.lucene.search.ConstantScoreQuery; import org.apache.lucene.search.DisjunctionMaxQuery; -import org.apache.lucene.search.Filter; -import org.apache.lucene.search.FilteredQuery; import org.apache.lucene.search.FuzzyQuery; import org.apache.lucene.search.MatchAllDocsQuery; import org.apache.lucene.search.MultiTermQuery; @@ -105,7 +103,6 @@ import org.junit.Before; import org.junit.Test; import java.io.IOException; -import java.lang.reflect.Field; import java.util.Arrays; import java.util.EnumSet; import java.util.List; @@ -645,11 +642,10 @@ public class SimpleIndexQueryParserTests extends ElasticsearchSingleNodeTest { public void testPrefiFilteredQueryBuilder() throws IOException { IndexQueryParserService queryParser = queryParser(); Query parsedQuery = queryParser.parse(filteredQuery(termQuery("name.first", "shay"), prefixQuery("name.first", "sh"))).query(); - assertThat(parsedQuery, instanceOf(FilteredQuery.class)); - FilteredQuery filteredQuery = (FilteredQuery) parsedQuery; - QueryWrapperFilter filter = (QueryWrapperFilter) filteredQuery.getFilter(); - PrefixQuery prefixQuery = (PrefixQuery) filter.getQuery(); - assertThat(prefixQuery.getPrefix(), equalTo(new Term("name.first", "sh"))); + Query expected = Queries.filtered( + new TermQuery(new Term("name.first", "shay")), + new PrefixQuery(new Term("name.first", "sh"))); + assertEquals(expected, parsedQuery); } @Test @@ -657,11 +653,10 @@ public class SimpleIndexQueryParserTests extends ElasticsearchSingleNodeTest { IndexQueryParserService queryParser = queryParser(); String query = copyToStringFromClasspath("/org/elasticsearch/index/query/prefix-filter.json"); Query parsedQuery = queryParser.parse(query).query(); - assertThat(parsedQuery, instanceOf(FilteredQuery.class)); - FilteredQuery filteredQuery = (FilteredQuery) parsedQuery; - QueryWrapperFilter filter = (QueryWrapperFilter) filteredQuery.getFilter(); - PrefixQuery prefixQuery = (PrefixQuery) filter.getQuery(); - assertThat(prefixQuery.getPrefix(), equalTo(new Term("name.first", "sh"))); + Query expected = Queries.filtered( + new TermQuery(new Term("name.first", "shay")), + new PrefixQuery(new Term("name.first", "sh"))); + assertEquals(expected, parsedQuery); } @Test @@ -670,11 +665,10 @@ public class SimpleIndexQueryParserTests extends ElasticsearchSingleNodeTest { String query = copyToStringFromClasspath("/org/elasticsearch/index/query/prefix-filter-named.json"); ParsedQuery parsedQuery = queryParser.parse(query); assertThat(parsedQuery.namedFilters().containsKey("test"), equalTo(true)); - assertThat(parsedQuery.query(), instanceOf(FilteredQuery.class)); - FilteredQuery filteredQuery = (FilteredQuery) parsedQuery.query(); - QueryWrapperFilter filter = (QueryWrapperFilter) filteredQuery.getFilter(); - PrefixQuery prefixQuery = (PrefixQuery) filter.getQuery(); - assertThat(prefixQuery.getPrefix(), equalTo(new Term("name.first", "sh"))); + Query expected = Queries.filtered( + new TermQuery(new Term("name.first", "shay")), + new PrefixQuery(new Term("name.first", "sh"))); + assertEquals(expected, parsedQuery.query()); } @Test @@ -742,14 +736,10 @@ public class SimpleIndexQueryParserTests extends ElasticsearchSingleNodeTest { IndexQueryParserService queryParser = queryParser(); String query = copyToStringFromClasspath("/org/elasticsearch/index/query/regexp-filter.json"); Query parsedQuery = queryParser.parse(query).query(); - assertThat(parsedQuery, instanceOf(FilteredQuery.class)); - Filter filter = ((FilteredQuery) parsedQuery).getFilter(); - assertThat(filter, instanceOf(QueryWrapperFilter.class)); - Query q = ((QueryWrapperFilter) filter).getQuery(); - assertThat(q, instanceOf(RegexpQuery.class)); - RegexpQuery regexpQuery = (RegexpQuery) q; - assertThat(regexpQuery.getField(), equalTo("name.first")); - assertThat(regexpQuery.toString(), containsString("s.*y")); + Query expected = Queries.filtered( + new TermQuery(new Term("name.first", "shay")), + new RegexpQuery(new Term("name.first", "s.*y"))); + assertEquals(expected, parsedQuery); } @Test @@ -757,14 +747,10 @@ public class SimpleIndexQueryParserTests extends ElasticsearchSingleNodeTest { IndexQueryParserService queryParser = queryParser(); String query = copyToStringFromClasspath("/org/elasticsearch/index/query/regexp-filter-max-determinized-states.json"); Query parsedQuery = queryParser.parse(query).query(); - assertThat(parsedQuery, instanceOf(FilteredQuery.class)); - Filter filter = ((FilteredQuery) parsedQuery).getFilter(); - assertThat(filter, instanceOf(QueryWrapperFilter.class)); - Query q = ((QueryWrapperFilter) filter).getQuery(); - assertThat(q, instanceOf(RegexpQuery.class)); - RegexpQuery regexpQuery = (RegexpQuery) q; - assertThat(regexpQuery.getField(), equalTo("name.first")); - assertThat(regexpQuery.toString(), containsString("s.*y")); + Query expected = Queries.filtered( + new TermQuery(new Term("name.first", "shay")), + new RegexpQuery(new Term("name.first", "s.*y"))); + assertEquals(expected, parsedQuery); } @Test @@ -773,14 +759,10 @@ public class SimpleIndexQueryParserTests extends ElasticsearchSingleNodeTest { String query = copyToStringFromClasspath("/org/elasticsearch/index/query/regexp-filter-named.json"); ParsedQuery parsedQuery = queryParser.parse(query); assertThat(parsedQuery.namedFilters().containsKey("test"), equalTo(true)); - assertThat(parsedQuery.query(), instanceOf(FilteredQuery.class)); - Filter filter = ((FilteredQuery) parsedQuery.query()).getFilter(); - assertThat(filter, instanceOf(QueryWrapperFilter.class)); - Query q = ((QueryWrapperFilter) filter).getQuery(); - assertThat(q, instanceOf(RegexpQuery.class)); - RegexpQuery regexpQuery = (RegexpQuery) q; - assertThat(regexpQuery.getField(), equalTo("name.first")); - assertThat(regexpQuery.toString(), containsString("s.*y")); + Query expected = Queries.filtered( + new TermQuery(new Term("name.first", "shay")), + new RegexpQuery(new Term("name.first", "s.*y"))); + assertEquals(expected, parsedQuery.query()); } @Test @@ -788,13 +770,10 @@ public class SimpleIndexQueryParserTests extends ElasticsearchSingleNodeTest { IndexQueryParserService queryParser = queryParser(); String query = copyToStringFromClasspath("/org/elasticsearch/index/query/regexp-filter-flags.json"); ParsedQuery parsedQuery = queryParser.parse(query); - assertThat(parsedQuery.query(), instanceOf(FilteredQuery.class)); - Filter filter = ((FilteredQuery) parsedQuery.query()).getFilter(); - assertThat(filter, instanceOf(QueryWrapperFilter.class)); - Query q = ((QueryWrapperFilter) filter).getQuery(); - assertThat(q, instanceOf(RegexpQuery.class)); - RegexpQuery regexpQuery = (RegexpQuery) q; - assertThat(regexpQuery.toString(), equalTo("name.first:/s.*y/")); + Query expected = Queries.filtered( + new TermQuery(new Term("name.first", "shay")), + new RegexpQuery(new Term("name.first", "s.*y"))); + assertEquals(expected, parsedQuery.query()); } @Test @@ -802,13 +781,10 @@ public class SimpleIndexQueryParserTests extends ElasticsearchSingleNodeTest { IndexQueryParserService queryParser = queryParser(); String query = copyToStringFromClasspath("/org/elasticsearch/index/query/regexp-filter-flags-named-cached.json"); ParsedQuery parsedQuery = queryParser.parse(query); - assertThat(parsedQuery.query(), instanceOf(FilteredQuery.class)); - Filter filter = ((FilteredQuery) parsedQuery.query()).getFilter(); - assertThat(filter, instanceOf(QueryWrapperFilter.class)); - Query q = ((QueryWrapperFilter) filter).getQuery(); - assertThat(q, instanceOf(RegexpQuery.class)); - RegexpQuery regexpQuery = (RegexpQuery) q; - assertThat(regexpQuery.toString(), equalTo("name.first:/s.*y/")); + Query expected = Queries.filtered( + new TermQuery(new Term("name.first", "shay")), + new RegexpQuery(new Term("name.first", "s.*y"))); + assertEquals(expected, parsedQuery.query()); } @Test @@ -900,9 +876,9 @@ public class SimpleIndexQueryParserTests extends ElasticsearchSingleNodeTest { public void testRangeFilteredQueryBuilder() throws IOException { IndexQueryParserService queryParser = queryParser(); Query parsedQuery = queryParser.parse(filteredQuery(termQuery("name.first", "shay"), rangeQuery("age").from(23).to(54).includeLower(true).includeUpper(false))).query(); - FilteredQuery expected = new FilteredQuery( + Query expected = Queries.filtered( new TermQuery(new Term("name.first", "shay")), - new QueryWrapperFilter(NumericRangeQuery.newLongRange("age", 23L, 54L, true, false))); + NumericRangeQuery.newLongRange("age", 23L, 54L, true, false)); assertEquals(expected, parsedQuery); } @@ -911,9 +887,9 @@ public class SimpleIndexQueryParserTests extends ElasticsearchSingleNodeTest { IndexQueryParserService queryParser = queryParser(); String query = copyToStringFromClasspath("/org/elasticsearch/index/query/range-filter.json"); Query parsedQuery = queryParser.parse(query).query(); - FilteredQuery expected = new FilteredQuery( + Query expected = Queries.filtered( new TermQuery(new Term("name.first", "shay")), - new QueryWrapperFilter(NumericRangeQuery.newLongRange("age", 23L, 54L, true, false))); + NumericRangeQuery.newLongRange("age", 23L, 54L, true, false)); assertEquals(expected, parsedQuery); } @@ -922,9 +898,9 @@ public class SimpleIndexQueryParserTests extends ElasticsearchSingleNodeTest { IndexQueryParserService queryParser = queryParser(); String query = copyToStringFromClasspath("/org/elasticsearch/index/query/range-filter-named.json"); Query parsedQuery = queryParser.parse(query).query(); - FilteredQuery expected = new FilteredQuery( + Query expected = Queries.filtered( new TermQuery(new Term("name.first", "shay")), - new QueryWrapperFilter(NumericRangeQuery.newLongRange("age", 23L, 54L, true, false))); + NumericRangeQuery.newLongRange("age", 23L, 54L, true, false)); assertEquals(expected, parsedQuery); } @@ -939,9 +915,9 @@ public class SimpleIndexQueryParserTests extends ElasticsearchSingleNodeTest { filter.add(new TermQuery(new Term("name.first", "shay2")), Occur.MUST_NOT); filter.add(new TermQuery(new Term("name.first", "shay3")), Occur.SHOULD); filter.setMinimumNumberShouldMatch(1); - FilteredQuery expected = new FilteredQuery( + Query expected = Queries.filtered( new TermQuery(new Term("name.first", "shay")), - new QueryWrapperFilter(filter)); + filter); assertEquals(expected, parsedQuery); } @@ -957,9 +933,9 @@ public class SimpleIndexQueryParserTests extends ElasticsearchSingleNodeTest { filter.add(new TermQuery(new Term("name.first", "shay2")), Occur.MUST_NOT); filter.add(new TermQuery(new Term("name.first", "shay3")), Occur.SHOULD); filter.setMinimumNumberShouldMatch(1); - FilteredQuery expected = new FilteredQuery( + Query expected = Queries.filtered( new TermQuery(new Term("name.first", "shay")), - new QueryWrapperFilter(filter)); + filter); assertEquals(expected, parsedQuery); } @@ -982,9 +958,9 @@ public class SimpleIndexQueryParserTests extends ElasticsearchSingleNodeTest { BooleanQuery and = new BooleanQuery(); and.add(new TermQuery(new Term("name.first", "shay1")), Occur.MUST); and.add(new TermQuery(new Term("name.first", "shay4")), Occur.MUST); - FilteredQuery expected = new FilteredQuery( + Query expected = Queries.filtered( new TermQuery(new Term("name.first", "shay")), - new QueryWrapperFilter(and)); + and); assertEquals(expected, parsedQuery); } @@ -996,9 +972,9 @@ public class SimpleIndexQueryParserTests extends ElasticsearchSingleNodeTest { BooleanQuery and = new BooleanQuery(); and.add(new TermQuery(new Term("name.first", "shay1")), Occur.MUST); and.add(new TermQuery(new Term("name.first", "shay4")), Occur.MUST); - FilteredQuery expected = new FilteredQuery( + Query expected = Queries.filtered( new TermQuery(new Term("name.first", "shay")), - new QueryWrapperFilter(and)); + and); assertEquals(expected, parsedQuery); } @@ -1010,9 +986,9 @@ public class SimpleIndexQueryParserTests extends ElasticsearchSingleNodeTest { BooleanQuery and = new BooleanQuery(); and.add(new TermQuery(new Term("name.first", "shay1")), Occur.MUST); and.add(new TermQuery(new Term("name.first", "shay4")), Occur.MUST); - FilteredQuery expected = new FilteredQuery( + Query expected = Queries.filtered( new TermQuery(new Term("name.first", "shay")), - new QueryWrapperFilter(and)); + and); assertEquals(expected, parsedQuery); } @@ -1035,9 +1011,9 @@ public class SimpleIndexQueryParserTests extends ElasticsearchSingleNodeTest { BooleanQuery or = new BooleanQuery(); or.add(new TermQuery(new Term("name.first", "shay1")), Occur.SHOULD); or.add(new TermQuery(new Term("name.first", "shay4")), Occur.SHOULD); - FilteredQuery expected = new FilteredQuery( + Query expected = Queries.filtered( new TermQuery(new Term("name.first", "shay")), - new QueryWrapperFilter(or)); + or); assertEquals(expected, parsedQuery); } @@ -1049,9 +1025,9 @@ public class SimpleIndexQueryParserTests extends ElasticsearchSingleNodeTest { BooleanQuery or = new BooleanQuery(); or.add(new TermQuery(new Term("name.first", "shay1")), Occur.SHOULD); or.add(new TermQuery(new Term("name.first", "shay4")), Occur.SHOULD); - FilteredQuery expected = new FilteredQuery( + Query expected = Queries.filtered( new TermQuery(new Term("name.first", "shay")), - new QueryWrapperFilter(or)); + or); assertEquals(expected, parsedQuery); } @@ -1068,10 +1044,9 @@ public class SimpleIndexQueryParserTests extends ElasticsearchSingleNodeTest { IndexQueryParserService queryParser = queryParser(); String query = copyToStringFromClasspath("/org/elasticsearch/index/query/not-filter.json"); Query parsedQuery = queryParser.parse(query).query(); - assertThat(parsedQuery, instanceOf(FilteredQuery.class)); - FilteredQuery expected = new FilteredQuery( + Query expected = Queries.filtered( new TermQuery(new Term("name.first", "shay")), - new QueryWrapperFilter(Queries.not(new TermQuery(new Term("name.first", "shay1"))))); + Queries.not(new TermQuery(new Term("name.first", "shay1")))); assertEquals(expected, parsedQuery); } @@ -1080,9 +1055,9 @@ public class SimpleIndexQueryParserTests extends ElasticsearchSingleNodeTest { IndexQueryParserService queryParser = queryParser(); String query = copyToStringFromClasspath("/org/elasticsearch/index/query/not-filter2.json"); Query parsedQuery = queryParser.parse(query).query(); - FilteredQuery expected = new FilteredQuery( + Query expected = Queries.filtered( new TermQuery(new Term("name.first", "shay")), - new QueryWrapperFilter(Queries.not(new TermQuery(new Term("name.first", "shay1"))))); + Queries.not(new TermQuery(new Term("name.first", "shay1")))); assertEquals(expected, parsedQuery); } @@ -1091,9 +1066,9 @@ public class SimpleIndexQueryParserTests extends ElasticsearchSingleNodeTest { IndexQueryParserService queryParser = queryParser(); String query = copyToStringFromClasspath("/org/elasticsearch/index/query/not-filter3.json"); Query parsedQuery = queryParser.parse(query).query(); - FilteredQuery expected = new FilteredQuery( + Query expected = Queries.filtered( new TermQuery(new Term("name.first", "shay")), - new QueryWrapperFilter(Queries.not(new TermQuery(new Term("name.first", "shay1"))))); + Queries.not(new TermQuery(new Term("name.first", "shay1")))); assertEquals(expected, parsedQuery); } @@ -1262,10 +1237,10 @@ public class SimpleIndexQueryParserTests extends ElasticsearchSingleNodeTest { public void testFilteredQueryBuilder() throws IOException { IndexQueryParserService queryParser = queryParser(); Query parsedQuery = queryParser.parse(filteredQuery(termQuery("name.first", "shay"), termQuery("name.last", "banon"))).query(); - assertThat(parsedQuery, instanceOf(FilteredQuery.class)); - FilteredQuery filteredQuery = (FilteredQuery) parsedQuery; - assertThat(((TermQuery) filteredQuery.getQuery()).getTerm(), equalTo(new Term("name.first", "shay"))); - assertThat(getTerm(filteredQuery.getFilter()), equalTo(new Term("name.last", "banon"))); + Query expected = Queries.filtered( + new TermQuery(new Term("name.first", "shay")), + new TermQuery(new Term("name.last", "banon"))); + assertEquals(expected, parsedQuery); } @Test @@ -1273,10 +1248,10 @@ public class SimpleIndexQueryParserTests extends ElasticsearchSingleNodeTest { IndexQueryParserService queryParser = queryParser(); String query = copyToStringFromClasspath("/org/elasticsearch/index/query/filtered-query.json"); Query parsedQuery = queryParser.parse(query).query(); - assertThat(parsedQuery, instanceOf(FilteredQuery.class)); - FilteredQuery filteredQuery = (FilteredQuery) parsedQuery; - assertThat(((TermQuery) filteredQuery.getQuery()).getTerm(), equalTo(new Term("name.first", "shay"))); - assertThat(getTerm(filteredQuery.getFilter()), equalTo(new Term("name.last", "banon"))); + Query expected = Queries.filtered( + new TermQuery(new Term("name.first", "shay")), + new TermQuery(new Term("name.last", "banon"))); + assertEquals(expected, parsedQuery); } @Test @@ -1284,10 +1259,10 @@ public class SimpleIndexQueryParserTests extends ElasticsearchSingleNodeTest { IndexQueryParserService queryParser = queryParser(); String query = copyToStringFromClasspath("/org/elasticsearch/index/query/filtered-query2.json"); Query parsedQuery = queryParser.parse(query).query(); - assertThat(parsedQuery, instanceOf(FilteredQuery.class)); - FilteredQuery filteredQuery = (FilteredQuery) parsedQuery; - assertThat(((TermQuery) filteredQuery.getQuery()).getTerm(), equalTo(new Term("name.first", "shay"))); - assertThat(getTerm(filteredQuery.getFilter()), equalTo(new Term("name.last", "banon"))); + Query expected = Queries.filtered( + new TermQuery(new Term("name.first", "shay")), + new TermQuery(new Term("name.last", "banon"))); + assertEquals(expected, parsedQuery); } @Test @@ -1295,15 +1270,10 @@ public class SimpleIndexQueryParserTests extends ElasticsearchSingleNodeTest { IndexQueryParserService queryParser = queryParser(); String query = copyToStringFromClasspath("/org/elasticsearch/index/query/filtered-query3.json"); Query parsedQuery = queryParser.parse(query).query(); - assertThat(parsedQuery, instanceOf(FilteredQuery.class)); - FilteredQuery filteredQuery = (FilteredQuery) parsedQuery; - assertThat(((TermQuery) filteredQuery.getQuery()).getTerm(), equalTo(new Term("name.first", "shay"))); - - QueryWrapperFilter filter = (QueryWrapperFilter) filteredQuery.getFilter(); - NumericRangeQuery rangeQuery = (NumericRangeQuery) filter.getQuery(); - assertThat(rangeQuery.getField(), equalTo("age")); - assertThat(rangeQuery.getMin().intValue(), equalTo(23)); - assertThat(rangeQuery.getMax().intValue(), equalTo(54)); + Query expected = Queries.filtered( + new TermQuery(new Term("name.first", "shay")), + NumericRangeQuery.newLongRange("age", 23L, 54L, true, false)); + assertEquals(expected, parsedQuery); } @Test @@ -1311,13 +1281,12 @@ public class SimpleIndexQueryParserTests extends ElasticsearchSingleNodeTest { IndexQueryParserService queryParser = queryParser(); String query = copyToStringFromClasspath("/org/elasticsearch/index/query/filtered-query4.json"); Query parsedQuery = queryParser.parse(query).query(); - assertThat(parsedQuery, instanceOf(FilteredQuery.class)); - FilteredQuery filteredQuery = (FilteredQuery) parsedQuery; - WildcardQuery wildcardQuery = (WildcardQuery) filteredQuery.getQuery(); - assertThat(wildcardQuery.getTerm(), equalTo(new Term("name.first", "sh*"))); - assertThat((double) wildcardQuery.getBoost(), closeTo(1.1, 0.001)); - - assertThat(getTerm(filteredQuery.getFilter()), equalTo(new Term("name.last", "banon"))); + Query expectedQuery = new WildcardQuery(new Term("name.first", "sh*")); + expectedQuery.setBoost(1.1f); + Query expected = Queries.filtered( + expectedQuery, + new TermQuery(new Term("name.last", "banon"))); + assertEquals(expected, parsedQuery); } @Test @@ -1325,12 +1294,10 @@ public class SimpleIndexQueryParserTests extends ElasticsearchSingleNodeTest { IndexQueryParserService queryParser = queryParser(); String query = copyToStringFromClasspath("/org/elasticsearch/index/query/term-filter.json"); Query parsedQuery = queryParser.parse(query).query(); - assertThat(parsedQuery, instanceOf(FilteredQuery.class)); - FilteredQuery filteredQuery = (FilteredQuery) parsedQuery; - QueryWrapperFilter filter = (QueryWrapperFilter) filteredQuery.getFilter(); - TermQuery termQuery = (TermQuery) filter.getQuery(); - assertThat(termQuery.getTerm().field(), equalTo("name.last")); - assertThat(termQuery.getTerm().text(), equalTo("banon")); + Query expected = Queries.filtered( + new TermQuery(new Term("name.first", "shay")), + new TermQuery(new Term("name.last", "banon"))); + assertEquals(expected, parsedQuery); } @Test @@ -1339,22 +1306,20 @@ public class SimpleIndexQueryParserTests extends ElasticsearchSingleNodeTest { String query = copyToStringFromClasspath("/org/elasticsearch/index/query/term-filter-named.json"); ParsedQuery parsedQuery = queryParser.parse(query); assertThat(parsedQuery.namedFilters().containsKey("test"), equalTo(true)); - assertThat(parsedQuery.query(), instanceOf(FilteredQuery.class)); - FilteredQuery filteredQuery = (FilteredQuery) parsedQuery.query(); - QueryWrapperFilter filter = (QueryWrapperFilter) filteredQuery.getFilter(); - TermQuery termQuery = (TermQuery) filter.getQuery(); - assertThat(termQuery.getTerm().field(), equalTo("name.last")); - assertThat(termQuery.getTerm().text(), equalTo("banon")); + Query expected = Queries.filtered( + new TermQuery(new Term("name.first", "shay")), + new TermQuery(new Term("name.last", "banon"))); + assertEquals(expected, parsedQuery.query()); } @Test public void testTermsFilterQueryBuilder() throws Exception { IndexQueryParserService queryParser = queryParser(); Query parsedQuery = queryParser.parse(filteredQuery(termQuery("name.first", "shay"), termsQuery("name.last", "banon", "kimchy"))).query(); - assertThat(parsedQuery, instanceOf(FilteredQuery.class)); - FilteredQuery filteredQuery = (FilteredQuery) parsedQuery; - QueryWrapperFilter filter = (QueryWrapperFilter) filteredQuery.getFilter(); - assertThat(filter.getQuery(), instanceOf(TermsQuery.class)); + Query expected = Queries.filtered( + new TermQuery(new Term("name.first", "shay")), + new TermsQuery("name.last", new BytesRef("banon"), new BytesRef("kimchy"))); + assertEquals(expected, parsedQuery); } @@ -1363,10 +1328,10 @@ public class SimpleIndexQueryParserTests extends ElasticsearchSingleNodeTest { IndexQueryParserService queryParser = queryParser(); String query = copyToStringFromClasspath("/org/elasticsearch/index/query/terms-filter.json"); Query parsedQuery = queryParser.parse(query).query(); - assertThat(parsedQuery, instanceOf(FilteredQuery.class)); - FilteredQuery filteredQuery = (FilteredQuery) parsedQuery; - QueryWrapperFilter filter = (QueryWrapperFilter) filteredQuery.getFilter(); - assertThat(filter.getQuery(), instanceOf(TermsQuery.class)); + Query expected = Queries.filtered( + new TermQuery(new Term("name.first", "shay")), + new TermsQuery("name.last", new BytesRef("banon"), new BytesRef("kimchy"))); + assertEquals(expected, parsedQuery); } @Test @@ -1375,10 +1340,10 @@ public class SimpleIndexQueryParserTests extends ElasticsearchSingleNodeTest { String query = copyToStringFromClasspath("/org/elasticsearch/index/query/terms-filter-named.json"); ParsedQuery parsedQuery = queryParser.parse(query); assertThat(parsedQuery.namedFilters().containsKey("test"), equalTo(true)); - assertThat(parsedQuery.query(), instanceOf(FilteredQuery.class)); - FilteredQuery filteredQuery = (FilteredQuery) parsedQuery.query(); - QueryWrapperFilter filter = (QueryWrapperFilter) filteredQuery.getFilter(); - assertThat(filter.getQuery(), instanceOf(TermsQuery.class)); + Query expected = Queries.filtered( + new TermQuery(new Term("name.first", "shay")), + new TermsQuery("name.last", new BytesRef("banon"), new BytesRef("kimchy"))); + assertEquals(expected, parsedQuery.query()); } @Test @@ -1685,14 +1650,10 @@ public class SimpleIndexQueryParserTests extends ElasticsearchSingleNodeTest { public void testQueryQueryBuilder() throws Exception { IndexQueryParserService queryParser = queryParser(); Query parsedQuery = queryParser.parse(filteredQuery(termQuery("name.first", "shay"), termQuery("name.last", "banon"))).query(); - assertThat(parsedQuery, instanceOf(FilteredQuery.class)); - FilteredQuery filteredQuery = (FilteredQuery) parsedQuery; - QueryWrapperFilter queryWrapperFilter = (QueryWrapperFilter) filteredQuery.getFilter(); - Field field = QueryWrapperFilter.class.getDeclaredField("query"); - field.setAccessible(true); - Query wrappedQuery = (Query) field.get(queryWrapperFilter); - assertThat(wrappedQuery, instanceOf(TermQuery.class)); - assertThat(((TermQuery) wrappedQuery).getTerm(), equalTo(new Term("name.last", "banon"))); + Query expected = Queries.filtered( + new TermQuery(new Term("name.first", "shay")), + new TermQuery(new Term("name.last", "banon"))); + assertEquals(expected, parsedQuery); } @Test @@ -1700,10 +1661,10 @@ public class SimpleIndexQueryParserTests extends ElasticsearchSingleNodeTest { IndexQueryParserService queryParser = queryParser(); String query = copyToStringFromClasspath("/org/elasticsearch/index/query/query-filter.json"); Query parsedQuery = queryParser.parse(query).query(); - assertThat(parsedQuery, instanceOf(FilteredQuery.class)); - FilteredQuery filteredQuery = (FilteredQuery) parsedQuery; - QueryWrapperFilter queryWrapperFilter = (QueryWrapperFilter) filteredQuery.getFilter(); - assertEquals(new ConstantScoreQuery(new TermQuery(new Term("name.last", "banon"))), queryWrapperFilter.getQuery()); + Query expected = Queries.filtered( + new TermQuery(new Term("name.first", "shay")), + new ConstantScoreQuery(new TermQuery(new Term("name.last", "banon")))); + assertEquals(expected, parsedQuery); } @Test @@ -1712,11 +1673,10 @@ public class SimpleIndexQueryParserTests extends ElasticsearchSingleNodeTest { String query = copyToStringFromClasspath("/org/elasticsearch/index/query/fquery-filter.json"); ParsedQuery parsedQuery = queryParser.parse(query); assertThat(parsedQuery.namedFilters().containsKey("test"), equalTo(true)); - assertThat(parsedQuery.query(), instanceOf(FilteredQuery.class)); - FilteredQuery filteredQuery = (FilteredQuery) parsedQuery.query(); - QueryWrapperFilter queryWrapperFilter = (QueryWrapperFilter) filteredQuery.getFilter(); - Query wrappedQuery = queryWrapperFilter.getQuery(); - assertEquals(new ConstantScoreQuery(new TermQuery(new Term("name.last", "banon"))), wrappedQuery); + Query expected = Queries.filtered( + new TermQuery(new Term("name.first", "shay")), + new ConstantScoreQuery(new TermQuery(new Term("name.last", "banon")))); + assertEquals(expected, parsedQuery.query()); } @Test @@ -2413,7 +2373,7 @@ public class SimpleIndexQueryParserTests extends ElasticsearchSingleNodeTest { String query = copyToStringFromClasspath("/org/elasticsearch/index/query/fquery-with-empty-bool-query.json"); XContentParser parser = XContentHelper.createParser(new BytesArray(query)); ParsedQuery parsedQuery = queryParser.parseInnerFilter(parser); - assertEquals(new ConstantScoreQuery(new FilteredQuery(new TermQuery(new Term("text", "apache")), new QueryWrapperFilter(new TermQuery(new Term("text", "apache"))))), parsedQuery.query()); + assertEquals(new ConstantScoreQuery(Queries.filtered(new TermQuery(new Term("text", "apache")), new TermQuery(new Term("text", "apache")))), parsedQuery.query()); } @Test @@ -2569,10 +2529,14 @@ public class SimpleIndexQueryParserTests extends ElasticsearchSingleNodeTest { public void testBooleanParsesFilter() throws Exception { IndexQueryParserService queryParser = queryParser(); // single clause, serialized as inner object - Query q = queryParser.parse(boolQuery().should(dummyQuery()).must(dummyQuery()).mustNot(dummyQuery())).query(); + Query q = queryParser.parse(boolQuery() + .should(dummyQuery()) + .must(dummyQuery()) + .filter(dummyQuery()) + .mustNot(dummyQuery())).query(); assertThat(q, instanceOf(BooleanQuery.class)); BooleanQuery bq = (BooleanQuery) q; - assertEquals(3, bq.clauses().size()); + assertEquals(4, bq.clauses().size()); for (BooleanClause clause : bq.clauses()) { DummyQuery dummy = (DummyQuery) clause.getQuery(); switch (clause.getOccur()) { @@ -2593,10 +2557,11 @@ public class SimpleIndexQueryParserTests extends ElasticsearchSingleNodeTest { q = queryParser.parse(boolQuery() .should(dummyQuery()).should(dummyQuery()) .must(dummyQuery()).must(dummyQuery()) + .filter(dummyQuery()).filter(dummyQuery()) .mustNot(dummyQuery()).mustNot(dummyQuery())).query(); assertThat(q, instanceOf(BooleanQuery.class)); bq = (BooleanQuery) q; - assertEquals(6, bq.clauses().size()); + assertEquals(8, bq.clauses().size()); for (BooleanClause clause : bq.clauses()) { DummyQuery dummy = (DummyQuery) clause.getQuery(); switch (clause.getOccur()) {