diff --git a/src/main/java/org/elasticsearch/search/aggregations/bucket/filter/FilterParser.java b/src/main/java/org/elasticsearch/search/aggregations/bucket/filter/FilterParser.java index 9c5efedf21fb4..c64e36116ef53 100644 --- a/src/main/java/org/elasticsearch/search/aggregations/bucket/filter/FilterParser.java +++ b/src/main/java/org/elasticsearch/search/aggregations/bucket/filter/FilterParser.java @@ -18,6 +18,7 @@ */ package org.elasticsearch.search.aggregations.bucket.filter; +import org.elasticsearch.common.lucene.search.MatchAllDocsFilter; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.index.query.ParsedFilter; import org.elasticsearch.search.aggregations.Aggregator; @@ -39,7 +40,8 @@ public String type() { @Override public AggregatorFactory parse(String aggregationName, XContentParser parser, SearchContext context) throws IOException { ParsedFilter filter = context.queryParserService().parseInnerFilter(parser); - return new FilterAggregator.Factory(aggregationName, filter.filter()); + + return new FilterAggregator.Factory(aggregationName, filter == null ? new MatchAllDocsFilter() : filter.filter()); } } diff --git a/src/main/java/org/elasticsearch/search/aggregations/bucket/filters/FiltersParser.java b/src/main/java/org/elasticsearch/search/aggregations/bucket/filters/FiltersParser.java index 87d115260187f..a8ae39494a34f 100644 --- a/src/main/java/org/elasticsearch/search/aggregations/bucket/filters/FiltersParser.java +++ b/src/main/java/org/elasticsearch/search/aggregations/bucket/filters/FiltersParser.java @@ -19,6 +19,7 @@ package org.elasticsearch.search.aggregations.bucket.filters; +import org.elasticsearch.common.lucene.search.MatchAllDocsFilter; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.index.query.ParsedFilter; import org.elasticsearch.search.SearchParseException; @@ -60,7 +61,7 @@ public AggregatorFactory parse(String aggregationName, XContentParser parser, Se key = parser.currentName(); } else { ParsedFilter filter = context.queryParserService().parseInnerFilter(parser); - filters.add(new FiltersAggregator.KeyedFilter(key, filter.filter())); + filters.add(new FiltersAggregator.KeyedFilter(key, filter == null ? new MatchAllDocsFilter() : filter.filter())); } } } else { @@ -72,7 +73,8 @@ public AggregatorFactory parse(String aggregationName, XContentParser parser, Se int idx = 0; while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) { ParsedFilter filter = context.queryParserService().parseInnerFilter(parser); - filters.add(new FiltersAggregator.KeyedFilter(String.valueOf(idx), filter.filter())); + filters.add(new FiltersAggregator.KeyedFilter(String.valueOf(idx), filter == null ? new MatchAllDocsFilter() + : filter.filter())); idx++; } } else { diff --git a/src/test/java/org/elasticsearch/search/aggregations/bucket/FilterTests.java b/src/test/java/org/elasticsearch/search/aggregations/bucket/FilterTests.java index 2bdedcfeca239..de6cedf1444b7 100644 --- a/src/test/java/org/elasticsearch/search/aggregations/bucket/FilterTests.java +++ b/src/test/java/org/elasticsearch/search/aggregations/bucket/FilterTests.java @@ -21,6 +21,8 @@ import org.elasticsearch.ElasticsearchException; import org.elasticsearch.action.index.IndexRequestBuilder; import org.elasticsearch.action.search.SearchResponse; +import org.elasticsearch.index.query.AndFilterBuilder; +import org.elasticsearch.index.query.FilterBuilder; import org.elasticsearch.search.aggregations.bucket.filter.Filter; import org.elasticsearch.search.aggregations.bucket.histogram.Histogram; import org.elasticsearch.search.aggregations.metrics.avg.Avg; @@ -97,6 +99,20 @@ public void simple() throws Exception { assertThat(filter.getDocCount(), equalTo((long) numTag1Docs)); } + // See NullPointer issue when filters are empty: + // https://github.com/elasticsearch/elasticsearch/issues/8438 + @Test + public void emptyFilterDeclarations() throws Exception { + FilterBuilder emptyFilter = new AndFilterBuilder(); + SearchResponse response = client().prepareSearch("idx").addAggregation(filter("tag1").filter(emptyFilter)).execute().actionGet(); + + assertSearchResponse(response); + + Filter filter = response.getAggregations().get("tag1"); + assertThat(filter, notNullValue()); + assertThat(filter.getDocCount(), equalTo((long) numDocs)); + } + @Test public void withSubAggregation() throws Exception { SearchResponse response = client().prepareSearch("idx") diff --git a/src/test/java/org/elasticsearch/search/aggregations/bucket/FiltersTests.java b/src/test/java/org/elasticsearch/search/aggregations/bucket/FiltersTests.java index b0df05bc97c38..0c3292bda5555 100644 --- a/src/test/java/org/elasticsearch/search/aggregations/bucket/FiltersTests.java +++ b/src/test/java/org/elasticsearch/search/aggregations/bucket/FiltersTests.java @@ -22,6 +22,8 @@ import org.elasticsearch.ElasticsearchException; import org.elasticsearch.action.index.IndexRequestBuilder; import org.elasticsearch.action.search.SearchResponse; +import org.elasticsearch.index.query.AndFilterBuilder; +import org.elasticsearch.index.query.FilterBuilder; import org.elasticsearch.search.aggregations.bucket.filters.Filters; import org.elasticsearch.search.aggregations.bucket.histogram.Histogram; import org.elasticsearch.search.aggregations.metrics.avg.Avg; @@ -112,6 +114,27 @@ public void simple() throws Exception { assertThat(bucket.getDocCount(), equalTo((long) numTag2Docs)); } + // See NullPointer issue when filters are empty: + // https://github.com/elasticsearch/elasticsearch/issues/8438 + @Test + public void emptyFilterDeclarations() throws Exception { + FilterBuilder emptyFilter = new AndFilterBuilder(); + SearchResponse response = client().prepareSearch("idx") + .addAggregation(filters("tags").filter("all", emptyFilter).filter("tag1", termFilter("tag", "tag1"))).execute() + .actionGet(); + + assertSearchResponse(response); + + Filters filters = response.getAggregations().get("tags"); + assertThat(filters, notNullValue()); + Filters.Bucket allBucket = filters.getBucketByKey("all"); + assertThat(allBucket.getDocCount(), equalTo((long) numDocs)); + + Filters.Bucket bucket = filters.getBucketByKey("tag1"); + assertThat(bucket, Matchers.notNullValue()); + assertThat(bucket.getDocCount(), equalTo((long) numTag1Docs)); + } + @Test public void withSubAggregation() throws Exception { SearchResponse response = client().prepareSearch("idx")