From adc50e0796197eeaf5014db4556858b6a614c32f Mon Sep 17 00:00:00 2001 From: Elie Prudhomme Date: Thu, 18 Aug 2016 13:46:48 +0200 Subject: [PATCH] Fix bug on empty bucket --- .../InternalMultipleMetric.java | 4 +- .../MultipleMetricAggregator.java | 15 ++++++- .../multiplemetric/MultipleMetricParser.java | 6 +-- .../MultipleMetricAggregatorTest.java | 40 +++++++++++++++++++ 4 files changed, 56 insertions(+), 9 deletions(-) diff --git a/src/main/java/fr/v3d/elasticsearch/search/aggregations/metrics/multiplemetric/InternalMultipleMetric.java b/src/main/java/fr/v3d/elasticsearch/search/aggregations/metrics/multiplemetric/InternalMultipleMetric.java index 917201d..2ed3caa 100644 --- a/src/main/java/fr/v3d/elasticsearch/search/aggregations/metrics/multiplemetric/InternalMultipleMetric.java +++ b/src/main/java/fr/v3d/elasticsearch/search/aggregations/metrics/multiplemetric/InternalMultipleMetric.java @@ -50,12 +50,10 @@ public Type type() { return TYPE; } - @Override public double getValue(String name) { return value(name); } - @Override public long getDocCount(String name) { return (countsMap.get(name) != null) ? countsMap.get(name) : 0; } @@ -215,7 +213,7 @@ public XContentBuilder doXContentBody(XContentBuilder builder, Params params) th public final static AggregationStreams.Stream STREAM = new AggregationStreams.Stream() { - @Override + public InternalMultipleMetric readResult(StreamInput in) throws IOException { InternalMultipleMetric result = new InternalMultipleMetric(); result.readFrom(in); diff --git a/src/main/java/fr/v3d/elasticsearch/search/aggregations/metrics/multiplemetric/MultipleMetricAggregator.java b/src/main/java/fr/v3d/elasticsearch/search/aggregations/metrics/multiplemetric/MultipleMetricAggregator.java index dc3bb3d..121c25c 100644 --- a/src/main/java/fr/v3d/elasticsearch/search/aggregations/metrics/multiplemetric/MultipleMetricAggregator.java +++ b/src/main/java/fr/v3d/elasticsearch/search/aggregations/metrics/multiplemetric/MultipleMetricAggregator.java @@ -87,7 +87,7 @@ public LeafBucketCollector getLeafCollector(LeafReaderContext ctx, final LeafBuc if (valuesSourceMap == null) { return LeafBucketCollector.NO_OP_COLLECTOR; } - + final BigArrays bigArrays = context.bigArrays(); final Map doubleValuesMap = new HashMap(); @@ -204,9 +204,20 @@ public double metric(String name, long owningBucketOrdinal) { @Override public InternalAggregation buildAggregation(long owningBucketOrdinal) { + long maxSize = -1L; + for (Entry e: metricCountsMap.entrySet()) { + LongArray counts = e.getValue(); + if (counts.size() > maxSize) + maxSize = counts.size(); + } + + if (owningBucketOrdinal >= maxSize) { + return buildEmptyAggregation(); + } + HashMap scriptParamsMap = getScriptParamsMap(owningBucketOrdinal); Map countsMap = getCountsMap(owningBucketOrdinal); - + return new InternalMultipleMetric(name, metricParamsMap, scriptParamsMap, countsMap, pipelineAggregators(), metaData()); } diff --git a/src/main/java/fr/v3d/elasticsearch/search/aggregations/metrics/multiplemetric/MultipleMetricParser.java b/src/main/java/fr/v3d/elasticsearch/search/aggregations/metrics/multiplemetric/MultipleMetricParser.java index a194da5..53762de 100644 --- a/src/main/java/fr/v3d/elasticsearch/search/aggregations/metrics/multiplemetric/MultipleMetricParser.java +++ b/src/main/java/fr/v3d/elasticsearch/search/aggregations/metrics/multiplemetric/MultipleMetricParser.java @@ -21,8 +21,7 @@ public class MultipleMetricParser implements Aggregator.Parser { public static final String SUM_OPERATOR = "sum"; public static final String COUNT_OPERATOR = "count"; - - @Override + public String type() { return InternalMultipleMetric.TYPE.name(); } @@ -30,8 +29,7 @@ public String type() { public static boolean isValidOperator(String operator) { return (operator.equals(SUM_OPERATOR) || operator.equals(COUNT_OPERATOR)); } - - @Override + public AggregatorFactory parse(String aggregationName, XContentParser parser, SearchContext context) throws IOException { XContentParser.Token token; diff --git a/src/test/java/fr/v3d/elasticsearch/plugin/multiplemetric/MultipleMetricAggregatorTest.java b/src/test/java/fr/v3d/elasticsearch/plugin/multiplemetric/MultipleMetricAggregatorTest.java index 5b7dd9a..3488086 100644 --- a/src/test/java/fr/v3d/elasticsearch/plugin/multiplemetric/MultipleMetricAggregatorTest.java +++ b/src/test/java/fr/v3d/elasticsearch/plugin/multiplemetric/MultipleMetricAggregatorTest.java @@ -7,6 +7,7 @@ import fr.v3d.elasticsearch.search.aggregations.metrics.multiplemetric.SumBuilder; import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery; +import static org.elasticsearch.index.query.QueryBuilders.termQuery; import java.util.HashMap; import java.util.Map; @@ -69,6 +70,45 @@ public void assertMultipleMetricAggregation() { assertEquals(metrics.getDocCount("value2"), 10); } + + @Test + public void assertMultipleMetricAggregationWithEmptyFilter() { + String indexName = "test1"; + int size = 1; + + Map termsFactor = new HashMap(); + termsFactor.put("foo", 1); + termsFactor.put("bar", 1); + + buildTestDataset(1, indexName, "type1", size, termsFactor); + + TermsBuilder termsBuilder = new TermsBuilder("group_by") + .field("field0") + .subAggregation(new MultipleMetricBuilder("metrics") + .field(new SumBuilder("value1") + .field("value1") + .filter(new RangeQueryBuilder("value1").lt(0)) + ) + ); + + SearchResponse searchResponse = client().prepareSearch(indexName) + .setQuery(matchAllQuery()) //termQuery("field0", "foo") + .addAggregation(termsBuilder) + .execute().actionGet(); + + Terms terms = searchResponse.getAggregations().get("group_by"); + for (Map.Entry entry: termsFactor.entrySet()) { + String term = entry.getKey(); + assertNotNull(terms.getBucketByKey(term)); + assertNotNull(terms.getBucketByKey(term).getAggregations()); + assertNotNull(terms.getBucketByKey(term).getAggregations().get("metrics")); + + MultipleMetric metrics = terms.getBucketByKey(term).getAggregations().get("metrics"); + assertEquals(metrics.getValue("value1"), 0.0, 0.0); + assertEquals(metrics.getDocCount("value1"), 0); + } + } + @Test public void assertMultipleMetricAggregationWithScriptError() { String indexName = "test1";