Rander sum as zero if count is zero for stats aggregation (#26893) (#27193)

This commit is contained in:
kel 2017-11-02 11:02:47 -05:00 committed by Colin Goodheart-Smithe
parent 7791e72626
commit 55b9dfdd52
2 changed files with 57 additions and 2 deletions

View File

@ -192,7 +192,7 @@ public class InternalStats extends InternalNumericMetricsAggregation.MultiValue
builder.nullField(Fields.MIN); builder.nullField(Fields.MIN);
builder.nullField(Fields.MAX); builder.nullField(Fields.MAX);
builder.nullField(Fields.AVG); builder.nullField(Fields.AVG);
builder.nullField(Fields.SUM); builder.field(Fields.SUM, 0.0d);
} }
otherStatsToXContent(builder, params); otherStatsToXContent(builder, params);
return builder; return builder;

View File

@ -19,6 +19,9 @@
package org.elasticsearch.search.aggregations.metrics; package org.elasticsearch.search.aggregations.metrics;
import org.elasticsearch.common.io.stream.Writeable; import org.elasticsearch.common.io.stream.Writeable;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.json.JsonXContent;
import org.elasticsearch.search.DocValueFormat; import org.elasticsearch.search.DocValueFormat;
import org.elasticsearch.search.aggregations.ParsedAggregation; import org.elasticsearch.search.aggregations.ParsedAggregation;
import org.elasticsearch.search.aggregations.metrics.stats.InternalStats; import org.elasticsearch.search.aggregations.metrics.stats.InternalStats;
@ -26,6 +29,8 @@ import org.elasticsearch.search.aggregations.metrics.stats.ParsedStats;
import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator; import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
import org.elasticsearch.test.InternalAggregationTestCase; import org.elasticsearch.test.InternalAggregationTestCase;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -80,7 +85,7 @@ public class InternalStatsTests extends InternalAggregationTestCase<InternalStat
long count = aggregation.getCount(); long count = aggregation.getCount();
assertEquals(count, parsed.getCount()); assertEquals(count, parsed.getCount());
// for count == 0, fields are rendered as `null`, so we test that we parse to default values used also in the reduce phase // for count == 0, fields are rendered as `null`, so we test that we parse to default values used also in the reduce phase
assertEquals(count > 0 ? aggregation.getMin() : Double.POSITIVE_INFINITY , parsed.getMin(), 0); assertEquals(count > 0 ? aggregation.getMin() : Double.POSITIVE_INFINITY, parsed.getMin(), 0);
assertEquals(count > 0 ? aggregation.getMax() : Double.NEGATIVE_INFINITY, parsed.getMax(), 0); assertEquals(count > 0 ? aggregation.getMax() : Double.NEGATIVE_INFINITY, parsed.getMax(), 0);
assertEquals(count > 0 ? aggregation.getSum() : 0, parsed.getSum(), 0); assertEquals(count > 0 ? aggregation.getSum() : 0, parsed.getSum(), 0);
assertEquals(count > 0 ? aggregation.getAvg() : 0, parsed.getAvg(), 0); assertEquals(count > 0 ? aggregation.getAvg() : 0, parsed.getAvg(), 0);
@ -153,5 +158,55 @@ public class InternalStatsTests extends InternalAggregationTestCase<InternalStat
} }
return new InternalStats(name, count, sum, min, max, formatter, pipelineAggregators, metaData); return new InternalStats(name, count, sum, min, max, formatter, pipelineAggregators, metaData);
} }
public void testDoXContentBody() throws IOException {
// count is greater than zero
double min = randomDoubleBetween(-1000000, 1000000, true);
double max = randomDoubleBetween(-1000000, 1000000, true);
double sum = randomDoubleBetween(-1000000, 1000000, true);
int count = randomIntBetween(1, 10);
DocValueFormat format = randomNumericDocValueFormat();
InternalStats internalStats = createInstance("stats", count, sum, min, max, format, Collections.emptyList(), null);
XContentBuilder builder = JsonXContent.contentBuilder().prettyPrint();
builder.startObject();
internalStats.doXContentBody(builder, ToXContent.EMPTY_PARAMS);
builder.endObject();
String expected = "{\n" +
" \"count\" : " + count + ",\n" +
" \"min\" : " + min + ",\n" +
" \"max\" : " + max + ",\n" +
" \"avg\" : " + internalStats.getAvg() + ",\n" +
" \"sum\" : " + sum;
if (format != DocValueFormat.RAW) {
expected += ",\n"+
" \"min_as_string\" : \"" + format.format(internalStats.getMin()) + "\",\n" +
" \"max_as_string\" : \"" + format.format(internalStats.getMax()) + "\",\n" +
" \"avg_as_string\" : \"" + format.format(internalStats.getAvg()) + "\",\n" +
" \"sum_as_string\" : \"" + format.format(internalStats.getSum()) + "\"";
}
expected += "\n}";
assertEquals(expected, builder.string());
// count is zero
format = randomNumericDocValueFormat();
min = 0.0;
max = 0.0;
sum = 0.0;
count = 0;
internalStats = createInstance("stats", count, sum, min, max, format, Collections.emptyList(), null);
builder = JsonXContent.contentBuilder().prettyPrint();
builder.startObject();
internalStats.doXContentBody(builder, ToXContent.EMPTY_PARAMS);
builder.endObject();
assertEquals("{\n" +
" \"count\" : 0,\n" +
" \"min\" : null,\n" +
" \"max\" : null,\n" +
" \"avg\" : null,\n" +
" \"sum\" : 0.0\n" +
"}", builder.string());
}
} }