Skip to content

Commit

Permalink
Fixes array out of bounds for value count agg (#26038)
Browse files Browse the repository at this point in the history
#17379 fixed many metric aggs so that if the parent aggregation does not collect any documents an empty bucket value is returned instead of an ArrayOutOfBoundsException being thrown. Unfortunately the value count aggregation was mised from this fix.

This change applies this fix from #17379 for the value count aggregation.
  • Loading branch information
colings86 committed Aug 3, 2017
1 parent c83d4cc commit 12f1df3
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public void collect(int doc, long bucket) throws IOException {

@Override
public double metric(long owningBucketOrd) {
return valuesSource == null ? 0 : counts.get(owningBucketOrd);
return (valuesSource == null || owningBucketOrd >= counts.size()) ? 0 : counts.get(owningBucketOrd);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@
import org.elasticsearch.script.ScriptType;
import org.elasticsearch.script.SearchScript;
import org.elasticsearch.search.aggregations.InternalAggregation;
import org.elasticsearch.search.aggregations.bucket.filter.Filter;
import org.elasticsearch.search.aggregations.bucket.global.Global;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.metrics.valuecount.ValueCount;
import org.elasticsearch.search.lookup.LeafSearchLookup;
import org.elasticsearch.search.lookup.SearchLookup;
Expand All @@ -42,12 +44,16 @@
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
import static org.elasticsearch.search.aggregations.AggregationBuilders.count;
import static org.elasticsearch.search.aggregations.AggregationBuilders.global;
import static org.elasticsearch.search.aggregations.AggregationBuilders.terms;
import static org.elasticsearch.search.aggregations.AggregationBuilders.filter;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCount;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSearchResponse;
Expand Down Expand Up @@ -249,6 +255,35 @@ public void testDontCacheScripts() throws Exception {
.getMissCount(), equalTo(1L));
}

public void testOrderByEmptyAggregation() throws Exception {
SearchResponse searchResponse = client().prepareSearch("idx").setQuery(matchAllQuery())
.addAggregation(terms("terms").field("value").order(Terms.Order.compound(Terms.Order.aggregation("filter>count", true)))
.subAggregation(filter("filter", termQuery("value", 100)).subAggregation(count("count").field("value"))))
.get();

assertHitCount(searchResponse, 10);

Terms terms = searchResponse.getAggregations().get("terms");
assertThat(terms, notNullValue());
List<? extends Terms.Bucket> buckets = terms.getBuckets();
assertThat(buckets, notNullValue());
assertThat(buckets.size(), equalTo(10));

for (int i = 0; i < 10; i++) {
Terms.Bucket bucket = buckets.get(i);
assertThat(bucket, notNullValue());
assertThat(bucket.getKeyAsNumber(), equalTo((long) i + 1));
assertThat(bucket.getDocCount(), equalTo(1L));
Filter filter = bucket.getAggregations().get("filter");
assertThat(filter, notNullValue());
assertThat(filter.getDocCount(), equalTo(0L));
ValueCount count = filter.getAggregations().get("count");
assertThat(count, notNullValue());
assertThat(count.value(), equalTo(0.0));

}
}

/**
* Mock plugin for the {@link FieldValueScriptEngine}
*/
Expand Down

0 comments on commit 12f1df3

Please sign in to comment.