Merge pull request #11142 from jpountz/feature/bool_filter

Query DSL: Add `filter` clauses to `bool` queries.
This commit is contained in:
Adrien Grand 2015-05-13 12:25:32 +02:00
commit 472cc0af08
9 changed files with 235 additions and 212 deletions

View File

@ -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.

View File

@ -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 }

View File

@ -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.

View File

@ -31,11 +31,13 @@ import java.util.List;
*/
public class BoolQueryBuilder extends BaseQueryBuilder implements BoostableQueryBuilder<BoolQueryBuilder> {
private ArrayList<QueryBuilder> mustClauses = new ArrayList<>();
private final List<QueryBuilder> mustClauses = new ArrayList<>();
private ArrayList<QueryBuilder> mustNotClauses = new ArrayList<>();
private final List<QueryBuilder> mustNotClauses = new ArrayList<>();
private ArrayList<QueryBuilder> shouldClauses = new ArrayList<>();
private final List<QueryBuilder> filterClauses = new ArrayList<>();
private final List<QueryBuilder> 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 <b>must</b> appear in the matching documents.
* Adds a query that <b>must</b> 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 <b>must not</b> appear in the matching documents.
* Adds a query that <b>must</b> 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 <b>must not</b> 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) {

View File

@ -71,55 +71,73 @@ 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) {
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));
}
} else {
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.isValue()) {
if ("disable_coord".equals(currentFieldName) || "disableCoord".equals(currentFieldName)) {
disableCoord = parser.booleanValue();

View File

@ -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<FilteredQueryBuilder> {
private final QueryBuilder queryBuilder;

View File

@ -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);

View File

@ -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);
}

View File

@ -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()) {