diff --git a/src/main/java/org/elasticsearch/index/query/FilteredQueryBuilder.java b/src/main/java/org/elasticsearch/index/query/FilteredQueryBuilder.java index 525262dceb3..da93a65e49a 100644 --- a/src/main/java/org/elasticsearch/index/query/FilteredQueryBuilder.java +++ b/src/main/java/org/elasticsearch/index/query/FilteredQueryBuilder.java @@ -19,14 +19,13 @@ package org.elasticsearch.index.query; +import org.elasticsearch.common.Nullable; import org.elasticsearch.common.xcontent.XContentBuilder; import java.io.IOException; /** * A query that applies a filter to the results of another query. - * - * */ public class FilteredQueryBuilder extends BaseQueryBuilder { @@ -40,9 +39,9 @@ public class FilteredQueryBuilder extends BaseQueryBuilder { * A query that applies a filter to the results of another query. * * @param queryBuilder The query to apply the filter to - * @param filterBuilder The filter to apply on the query + * @param filterBuilder The filter to apply on the query (Can be null) */ - public FilteredQueryBuilder(QueryBuilder queryBuilder, FilterBuilder filterBuilder) { + public FilteredQueryBuilder(QueryBuilder queryBuilder, @Nullable FilterBuilder filterBuilder) { this.queryBuilder = queryBuilder; this.filterBuilder = filterBuilder; } @@ -61,8 +60,10 @@ public class FilteredQueryBuilder extends BaseQueryBuilder { builder.startObject(FilteredQueryParser.NAME); builder.field("query"); queryBuilder.toXContent(builder, params); - builder.field("filter"); - filterBuilder.toXContent(builder, params); + if (filterBuilder != null) { + builder.field("filter"); + filterBuilder.toXContent(builder, params); + } if (boost != -1) { builder.field("boost", boost); } diff --git a/src/main/java/org/elasticsearch/index/query/FilteredQueryParser.java b/src/main/java/org/elasticsearch/index/query/FilteredQueryParser.java index 080ff0d3a8a..5efa8eda57f 100644 --- a/src/main/java/org/elasticsearch/index/query/FilteredQueryParser.java +++ b/src/main/java/org/elasticsearch/index/query/FilteredQueryParser.java @@ -84,8 +84,9 @@ public class FilteredQueryParser implements QueryParser { if (query == null) { throw new QueryParsingException(parseContext.index(), "[filtered] requires 'query' element"); } + // we allow for null filter, so it makes compositions on the client side to be simpler if (filter == null) { - throw new QueryParsingException(parseContext.index(), "[filtered] requires 'filter' element"); + return query; } // cache if required diff --git a/src/main/java/org/elasticsearch/index/query/QueryBuilders.java b/src/main/java/org/elasticsearch/index/query/QueryBuilders.java index e2ef8b706e3..e32e947af18 100644 --- a/src/main/java/org/elasticsearch/index/query/QueryBuilders.java +++ b/src/main/java/org/elasticsearch/index/query/QueryBuilders.java @@ -23,8 +23,6 @@ import org.elasticsearch.common.Nullable; /** * A static factory for simple "import static" usage. - * - * */ public abstract class QueryBuilders { @@ -389,7 +387,7 @@ public abstract class QueryBuilders { * @param filterBuilder The filter to apply on the query * @deprecated Use filteredQuery instead (rename) */ - public static FilteredQueryBuilder filtered(QueryBuilder queryBuilder, FilterBuilder filterBuilder) { + public static FilteredQueryBuilder filtered(QueryBuilder queryBuilder, @Nullable FilterBuilder filterBuilder) { return new FilteredQueryBuilder(queryBuilder, filterBuilder); } @@ -399,7 +397,7 @@ public abstract class QueryBuilders { * @param queryBuilder The query to apply the filter to * @param filterBuilder The filter to apply on the query */ - public static FilteredQueryBuilder filteredQuery(QueryBuilder queryBuilder, FilterBuilder filterBuilder) { + public static FilteredQueryBuilder filteredQuery(QueryBuilder queryBuilder, @Nullable FilterBuilder filterBuilder) { return new FilteredQueryBuilder(queryBuilder, filterBuilder); } diff --git a/src/main/java/org/elasticsearch/index/query/QueryParseContext.java b/src/main/java/org/elasticsearch/index/query/QueryParseContext.java index 45fbf523ce5..a2869ca66b1 100644 --- a/src/main/java/org/elasticsearch/index/query/QueryParseContext.java +++ b/src/main/java/org/elasticsearch/index/query/QueryParseContext.java @@ -208,6 +208,10 @@ public class QueryParseContext { } token = parser.nextToken(); if (token != XContentParser.Token.FIELD_NAME) { + // empty filter + if (token == XContentParser.Token.END_OBJECT || token == XContentParser.Token.VALUE_NULL) { + return null; + } throw new QueryParsingException(index, "[_na] filter malformed, no field after start_object"); } String filterName = parser.currentName();