Aggregations: Fixes Filter and FiltersAggregation to work with empty query
This fix ensures the filter and filters aggregation will not throw a NPE when `{}` is passed in as a filter. Instead `{}` is interpreted as a MatchAllDocsQuery. Closes #17518
This commit is contained in:
parent
7037670aeb
commit
65a5366cba
|
@ -23,6 +23,7 @@ import org.elasticsearch.common.io.stream.StreamInput;
|
||||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.index.query.EmptyQueryBuilder;
|
import org.elasticsearch.index.query.EmptyQueryBuilder;
|
||||||
|
import org.elasticsearch.index.query.MatchAllQueryBuilder;
|
||||||
import org.elasticsearch.index.query.QueryBuilder;
|
import org.elasticsearch.index.query.QueryBuilder;
|
||||||
import org.elasticsearch.search.aggregations.AggregatorBuilder;
|
import org.elasticsearch.search.aggregations.AggregatorBuilder;
|
||||||
import org.elasticsearch.search.aggregations.AggregatorFactories;
|
import org.elasticsearch.search.aggregations.AggregatorFactories;
|
||||||
|
@ -51,8 +52,12 @@ public class FilterAggregatorBuilder extends AggregatorBuilder<FilterAggregatorB
|
||||||
if (filter == null) {
|
if (filter == null) {
|
||||||
throw new IllegalArgumentException("[filter] must not be null: [" + name + "]");
|
throw new IllegalArgumentException("[filter] must not be null: [" + name + "]");
|
||||||
}
|
}
|
||||||
|
if (filter instanceof EmptyQueryBuilder) {
|
||||||
|
this.filter = new MatchAllQueryBuilder();
|
||||||
|
} else {
|
||||||
this.filter = filter;
|
this.filter = filter;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AggregatorFactory<?> doBuild(AggregationContext context, AggregatorFactory<?> parent,
|
protected AggregatorFactory<?> doBuild(AggregationContext context, AggregatorFactory<?> parent,
|
||||||
|
|
|
@ -20,7 +20,6 @@ package org.elasticsearch.search.aggregations.bucket.filter;
|
||||||
|
|
||||||
import org.elasticsearch.common.ParsingException;
|
import org.elasticsearch.common.ParsingException;
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
import org.elasticsearch.index.query.MatchAllQueryBuilder;
|
|
||||||
import org.elasticsearch.index.query.QueryBuilder;
|
import org.elasticsearch.index.query.QueryBuilder;
|
||||||
import org.elasticsearch.index.query.QueryParseContext;
|
import org.elasticsearch.index.query.QueryParseContext;
|
||||||
import org.elasticsearch.search.aggregations.Aggregator;
|
import org.elasticsearch.search.aggregations.Aggregator;
|
||||||
|
@ -45,9 +44,7 @@ public class FilterParser implements Aggregator.Parser {
|
||||||
throw new ParsingException(null, "filter cannot be null in filter aggregation [{}]", aggregationName);
|
throw new ParsingException(null, "filter cannot be null in filter aggregation [{}]", aggregationName);
|
||||||
}
|
}
|
||||||
|
|
||||||
FilterAggregatorBuilder factory = new FilterAggregatorBuilder(aggregationName,
|
return new FilterAggregatorBuilder(aggregationName, filter);
|
||||||
filter == null ? new MatchAllQueryBuilder() : filter);
|
|
||||||
return factory;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -30,6 +30,7 @@ import org.elasticsearch.common.lucene.Lucene;
|
||||||
import org.elasticsearch.common.xcontent.ToXContent;
|
import org.elasticsearch.common.xcontent.ToXContent;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.index.query.EmptyQueryBuilder;
|
import org.elasticsearch.index.query.EmptyQueryBuilder;
|
||||||
|
import org.elasticsearch.index.query.MatchAllQueryBuilder;
|
||||||
import org.elasticsearch.index.query.QueryBuilder;
|
import org.elasticsearch.index.query.QueryBuilder;
|
||||||
import org.elasticsearch.search.aggregations.Aggregator;
|
import org.elasticsearch.search.aggregations.Aggregator;
|
||||||
import org.elasticsearch.search.aggregations.AggregatorFactories;
|
import org.elasticsearch.search.aggregations.AggregatorFactories;
|
||||||
|
@ -70,8 +71,12 @@ public class FiltersAggregator extends BucketsAggregator {
|
||||||
throw new IllegalArgumentException("[filter] must not be null");
|
throw new IllegalArgumentException("[filter] must not be null");
|
||||||
}
|
}
|
||||||
this.key = key;
|
this.key = key;
|
||||||
|
if (filter instanceof EmptyQueryBuilder) {
|
||||||
|
this.filter = new MatchAllQueryBuilder();
|
||||||
|
} else {
|
||||||
this.filter = filter;
|
this.filter = filter;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public String key() {
|
public String key() {
|
||||||
return key;
|
return key;
|
||||||
|
|
|
@ -23,6 +23,7 @@ import org.elasticsearch.action.index.IndexRequestBuilder;
|
||||||
import org.elasticsearch.action.search.SearchResponse;
|
import org.elasticsearch.action.search.SearchResponse;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.index.query.BoolQueryBuilder;
|
import org.elasticsearch.index.query.BoolQueryBuilder;
|
||||||
|
import org.elasticsearch.index.query.EmptyQueryBuilder;
|
||||||
import org.elasticsearch.index.query.QueryBuilder;
|
import org.elasticsearch.index.query.QueryBuilder;
|
||||||
import org.elasticsearch.search.aggregations.bucket.filter.Filter;
|
import org.elasticsearch.search.aggregations.bucket.filter.Filter;
|
||||||
import org.elasticsearch.search.aggregations.bucket.histogram.Histogram;
|
import org.elasticsearch.search.aggregations.bucket.histogram.Histogram;
|
||||||
|
@ -108,7 +109,18 @@ public class FilterIT extends ESIntegTestCase {
|
||||||
// See NullPointer issue when filters are empty:
|
// See NullPointer issue when filters are empty:
|
||||||
// https://github.com/elastic/elasticsearch/issues/8438
|
// https://github.com/elastic/elasticsearch/issues/8438
|
||||||
public void testEmptyFilterDeclarations() throws Exception {
|
public void testEmptyFilterDeclarations() throws Exception {
|
||||||
QueryBuilder emptyFilter = new BoolQueryBuilder();
|
QueryBuilder<?> emptyFilter = new BoolQueryBuilder();
|
||||||
|
SearchResponse response = client().prepareSearch("idx").addAggregation(filter("tag1", emptyFilter)).execute().actionGet();
|
||||||
|
|
||||||
|
assertSearchResponse(response);
|
||||||
|
|
||||||
|
Filter filter = response.getAggregations().get("tag1");
|
||||||
|
assertThat(filter, notNullValue());
|
||||||
|
assertThat(filter.getDocCount(), equalTo((long) numDocs));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testEmptyFilter() throws Exception {
|
||||||
|
QueryBuilder<?> emptyFilter = new EmptyQueryBuilder();
|
||||||
SearchResponse response = client().prepareSearch("idx").addAggregation(filter("tag1", emptyFilter)).execute().actionGet();
|
SearchResponse response = client().prepareSearch("idx").addAggregation(filter("tag1", emptyFilter)).execute().actionGet();
|
||||||
|
|
||||||
assertSearchResponse(response);
|
assertSearchResponse(response);
|
||||||
|
|
|
@ -24,6 +24,7 @@ import org.elasticsearch.action.index.IndexRequestBuilder;
|
||||||
import org.elasticsearch.action.search.SearchResponse;
|
import org.elasticsearch.action.search.SearchResponse;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.index.query.BoolQueryBuilder;
|
import org.elasticsearch.index.query.BoolQueryBuilder;
|
||||||
|
import org.elasticsearch.index.query.EmptyQueryBuilder;
|
||||||
import org.elasticsearch.index.query.QueryBuilder;
|
import org.elasticsearch.index.query.QueryBuilder;
|
||||||
import org.elasticsearch.search.aggregations.bucket.filters.Filters;
|
import org.elasticsearch.search.aggregations.bucket.filters.Filters;
|
||||||
import org.elasticsearch.search.aggregations.bucket.filters.FiltersAggregator.KeyedFilter;
|
import org.elasticsearch.search.aggregations.bucket.filters.FiltersAggregator.KeyedFilter;
|
||||||
|
@ -201,6 +202,32 @@ public class FiltersIT extends ESIntegTestCase {
|
||||||
assertThat((double) propertiesCounts[1], equalTo((double) sum / numTag2Docs));
|
assertThat((double) propertiesCounts[1], equalTo((double) sum / numTag2Docs));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testEmptyFilter() throws Exception {
|
||||||
|
QueryBuilder<?> emptyFilter = new EmptyQueryBuilder();
|
||||||
|
SearchResponse response = client().prepareSearch("idx").addAggregation(filters("tag1", emptyFilter)).execute().actionGet();
|
||||||
|
|
||||||
|
assertSearchResponse(response);
|
||||||
|
|
||||||
|
Filters filter = response.getAggregations().get("tag1");
|
||||||
|
assertThat(filter, notNullValue());
|
||||||
|
assertThat(filter.getBuckets().size(), equalTo(1));
|
||||||
|
assertThat(filter.getBuckets().get(0).getDocCount(), equalTo((long) numDocs));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testEmptyKeyedFilter() throws Exception {
|
||||||
|
QueryBuilder<?> emptyFilter = new EmptyQueryBuilder();
|
||||||
|
SearchResponse response = client().prepareSearch("idx").addAggregation(filters("tag1", new KeyedFilter("foo", emptyFilter)))
|
||||||
|
.execute().actionGet();
|
||||||
|
|
||||||
|
assertSearchResponse(response);
|
||||||
|
|
||||||
|
Filters filter = response.getAggregations().get("tag1");
|
||||||
|
assertThat(filter, notNullValue());
|
||||||
|
assertThat(filter.getBuckets().size(), equalTo(1));
|
||||||
|
assertThat(filter.getBuckets().get(0).getKey(), equalTo("foo"));
|
||||||
|
assertThat(filter.getBuckets().get(0).getDocCount(), equalTo((long) numDocs));
|
||||||
|
}
|
||||||
|
|
||||||
public void testAsSubAggregation() {
|
public void testAsSubAggregation() {
|
||||||
SearchResponse response = client().prepareSearch("idx")
|
SearchResponse response = client().prepareSearch("idx")
|
||||||
.addAggregation(
|
.addAggregation(
|
||||||
|
|
Loading…
Reference in New Issue