Query DSL: filtered query to support null filter or {} filter (in which case, just the query is executed), closes #1900.

This commit is contained in:
Shay Banon 2012-05-02 14:58:39 +03:00
parent 300fb4fa93
commit f8e6cc6fac
4 changed files with 15 additions and 11 deletions

View File

@ -19,14 +19,13 @@
package org.elasticsearch.index.query; package org.elasticsearch.index.query;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentBuilder;
import java.io.IOException; import java.io.IOException;
/** /**
* A query that applies a filter to the results of another query. * A query that applies a filter to the results of another query.
*
*
*/ */
public class FilteredQueryBuilder extends BaseQueryBuilder { 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. * A query that applies a filter to the results of another query.
* *
* @param queryBuilder The query to apply the filter to * @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.queryBuilder = queryBuilder;
this.filterBuilder = filterBuilder; this.filterBuilder = filterBuilder;
} }
@ -61,8 +60,10 @@ public class FilteredQueryBuilder extends BaseQueryBuilder {
builder.startObject(FilteredQueryParser.NAME); builder.startObject(FilteredQueryParser.NAME);
builder.field("query"); builder.field("query");
queryBuilder.toXContent(builder, params); queryBuilder.toXContent(builder, params);
if (filterBuilder != null) {
builder.field("filter"); builder.field("filter");
filterBuilder.toXContent(builder, params); filterBuilder.toXContent(builder, params);
}
if (boost != -1) { if (boost != -1) {
builder.field("boost", boost); builder.field("boost", boost);
} }

View File

@ -84,8 +84,9 @@ public class FilteredQueryParser implements QueryParser {
if (query == null) { if (query == null) {
throw new QueryParsingException(parseContext.index(), "[filtered] requires 'query' element"); 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) { if (filter == null) {
throw new QueryParsingException(parseContext.index(), "[filtered] requires 'filter' element"); return query;
} }
// cache if required // cache if required

View File

@ -23,8 +23,6 @@ import org.elasticsearch.common.Nullable;
/** /**
* A static factory for simple "import static" usage. * A static factory for simple "import static" usage.
*
*
*/ */
public abstract class QueryBuilders { public abstract class QueryBuilders {
@ -389,7 +387,7 @@ public abstract class QueryBuilders {
* @param filterBuilder The filter to apply on the query * @param filterBuilder The filter to apply on the query
* @deprecated Use filteredQuery instead (rename) * @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); return new FilteredQueryBuilder(queryBuilder, filterBuilder);
} }
@ -399,7 +397,7 @@ public abstract class QueryBuilders {
* @param queryBuilder The query to apply the filter to * @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
*/ */
public static FilteredQueryBuilder filteredQuery(QueryBuilder queryBuilder, FilterBuilder filterBuilder) { public static FilteredQueryBuilder filteredQuery(QueryBuilder queryBuilder, @Nullable FilterBuilder filterBuilder) {
return new FilteredQueryBuilder(queryBuilder, filterBuilder); return new FilteredQueryBuilder(queryBuilder, filterBuilder);
} }

View File

@ -208,6 +208,10 @@ public class QueryParseContext {
} }
token = parser.nextToken(); token = parser.nextToken();
if (token != XContentParser.Token.FIELD_NAME) { 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"); throw new QueryParsingException(index, "[_na] filter malformed, no field after start_object");
} }
String filterName = parser.currentName(); String filterName = parser.currentName();