Fixed an issue where and IndexOutOfBoundsException was thrown when a date_/histogram aggregation was defined on unmapped field and also had a sub aggregation. The root cause there was that in such case, the estimated bucket count was 0, and the code was not designed to handle that well.
Closes #5179
This commit is contained in:
parent
57fcd761f2
commit
164f7b981e
|
@ -73,9 +73,13 @@ public class AggregatorFactories {
|
||||||
ObjectArray<Aggregator> aggregators;
|
ObjectArray<Aggregator> aggregators;
|
||||||
|
|
||||||
{
|
{
|
||||||
aggregators = BigArrays.newObjectArray(estimatedBucketsCount, context.pageCacheRecycler());
|
// if estimated count is zero, we at least create a single aggregator.
|
||||||
|
// The estimated count is just an estimation and we can't rely on how it's estimated (that is, an
|
||||||
|
// estimation of 0 should not imply that we'll end up without any buckets)
|
||||||
|
long arraySize = estimatedBucketsCount > 0 ? estimatedBucketsCount : 1;
|
||||||
|
aggregators = BigArrays.newObjectArray(arraySize , context.pageCacheRecycler());
|
||||||
aggregators.set(0, first);
|
aggregators.set(0, first);
|
||||||
for (long i = 1; i < estimatedBucketsCount; ++i) {
|
for (long i = 1; i < arraySize; ++i) {
|
||||||
aggregators.set(i, createAndRegisterContextAware(parent.context(), factory, parent, estimatedBucketsCount));
|
aggregators.set(i, createAndRegisterContextAware(parent.context(), factory, parent, estimatedBucketsCount));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,18 +25,21 @@ import org.elasticsearch.action.index.IndexRequestBuilder;
|
||||||
import org.elasticsearch.action.search.SearchResponse;
|
import org.elasticsearch.action.search.SearchResponse;
|
||||||
import org.elasticsearch.common.settings.ImmutableSettings;
|
import org.elasticsearch.common.settings.ImmutableSettings;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
|
import org.elasticsearch.search.aggregations.bucket.histogram.Histogram;
|
||||||
import org.elasticsearch.search.aggregations.bucket.missing.Missing;
|
import org.elasticsearch.search.aggregations.bucket.missing.Missing;
|
||||||
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
|
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
|
||||||
import org.elasticsearch.test.ElasticsearchIntegrationTest;
|
import org.elasticsearch.test.ElasticsearchIntegrationTest;
|
||||||
|
import org.hamcrest.Matchers;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
|
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
|
||||||
import static org.elasticsearch.search.aggregations.AggregationBuilders.missing;
|
import static org.elasticsearch.search.aggregations.AggregationBuilders.*;
|
||||||
import static org.elasticsearch.search.aggregations.AggregationBuilders.terms;
|
|
||||||
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSearchResponse;
|
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSearchResponse;
|
||||||
import static org.hamcrest.CoreMatchers.equalTo;
|
import static org.hamcrest.CoreMatchers.equalTo;
|
||||||
|
import static org.hamcrest.CoreMatchers.is;
|
||||||
|
import static org.hamcrest.core.IsNull.notNullValue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -110,4 +113,34 @@ public class CombiTests extends ElasticsearchIntegrationTest {
|
||||||
}
|
}
|
||||||
assertTrue(values.isEmpty());
|
assertTrue(values.isEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Some top aggs (eg. date_/histogram) that are executed on unmapped fields, will generate an estimate count of buckets - zero.
|
||||||
|
* when the sub aggregator is then created, it will take this estimation into account. This used to cause
|
||||||
|
* and an ArrayIndexOutOfBoundsException...
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void subAggregationForTopAggregationOnUnmappedField() throws Exception {
|
||||||
|
|
||||||
|
prepareCreate("idx").addMapping("type", jsonBuilder()
|
||||||
|
.startObject()
|
||||||
|
.startObject("type").startObject("properties")
|
||||||
|
.startObject("name").field("type", "string").endObject()
|
||||||
|
.startObject("value").field("type", "integer").endObject()
|
||||||
|
.endObject().endObject()
|
||||||
|
.endObject()).execute().actionGet();
|
||||||
|
|
||||||
|
ensureSearchable("idx");
|
||||||
|
|
||||||
|
SearchResponse searchResponse = client().prepareSearch("idx")
|
||||||
|
.addAggregation(histogram("values").field("value1").interval(1)
|
||||||
|
.subAggregation(terms("names").field("name")))
|
||||||
|
.execute().actionGet();
|
||||||
|
|
||||||
|
assertThat(searchResponse.getHits().getTotalHits(), Matchers.equalTo(0l));
|
||||||
|
Histogram values = searchResponse.getAggregations().get("values");
|
||||||
|
assertThat(values, notNullValue());
|
||||||
|
assertThat(values.getBuckets().isEmpty(), is(true));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue