Skip to content

Commit 55b9dfd

Browse files
kelcolings86
kel
authored andcommitted
Rander sum as zero if count is zero for stats aggregation (#26893) (#27193)
1 parent 7791e72 commit 55b9dfd

File tree

2 files changed

+57
-2
lines changed

2 files changed

+57
-2
lines changed

core/src/main/java/org/elasticsearch/search/aggregations/metrics/stats/InternalStats.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ public XContentBuilder doXContentBody(XContentBuilder builder, Params params) th
192192
builder.nullField(Fields.MIN);
193193
builder.nullField(Fields.MAX);
194194
builder.nullField(Fields.AVG);
195-
builder.nullField(Fields.SUM);
195+
builder.field(Fields.SUM, 0.0d);
196196
}
197197
otherStatsToXContent(builder, params);
198198
return builder;

core/src/test/java/org/elasticsearch/search/aggregations/metrics/InternalStatsTests.java

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,18 @@
1919
package org.elasticsearch.search.aggregations.metrics;
2020

2121
import org.elasticsearch.common.io.stream.Writeable;
22+
import org.elasticsearch.common.xcontent.ToXContent;
23+
import org.elasticsearch.common.xcontent.XContentBuilder;
24+
import org.elasticsearch.common.xcontent.json.JsonXContent;
2225
import org.elasticsearch.search.DocValueFormat;
2326
import org.elasticsearch.search.aggregations.ParsedAggregation;
2427
import org.elasticsearch.search.aggregations.metrics.stats.InternalStats;
2528
import org.elasticsearch.search.aggregations.metrics.stats.ParsedStats;
2629
import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
2730
import org.elasticsearch.test.InternalAggregationTestCase;
2831

32+
import java.io.IOException;
33+
import java.util.Collections;
2934
import java.util.HashMap;
3035
import java.util.List;
3136
import java.util.Map;
@@ -80,7 +85,7 @@ static void assertStats(InternalStats aggregation, ParsedStats parsed) {
8085
long count = aggregation.getCount();
8186
assertEquals(count, parsed.getCount());
8287
// for count == 0, fields are rendered as `null`, so we test that we parse to default values used also in the reduce phase
83-
assertEquals(count > 0 ? aggregation.getMin() : Double.POSITIVE_INFINITY , parsed.getMin(), 0);
88+
assertEquals(count > 0 ? aggregation.getMin() : Double.POSITIVE_INFINITY, parsed.getMin(), 0);
8489
assertEquals(count > 0 ? aggregation.getMax() : Double.NEGATIVE_INFINITY, parsed.getMax(), 0);
8590
assertEquals(count > 0 ? aggregation.getSum() : 0, parsed.getSum(), 0);
8691
assertEquals(count > 0 ? aggregation.getAvg() : 0, parsed.getAvg(), 0);
@@ -153,5 +158,55 @@ protected InternalStats mutateInstance(InternalStats instance) {
153158
}
154159
return new InternalStats(name, count, sum, min, max, formatter, pipelineAggregators, metaData);
155160
}
161+
162+
public void testDoXContentBody() throws IOException {
163+
// count is greater than zero
164+
double min = randomDoubleBetween(-1000000, 1000000, true);
165+
double max = randomDoubleBetween(-1000000, 1000000, true);
166+
double sum = randomDoubleBetween(-1000000, 1000000, true);
167+
int count = randomIntBetween(1, 10);
168+
DocValueFormat format = randomNumericDocValueFormat();
169+
InternalStats internalStats = createInstance("stats", count, sum, min, max, format, Collections.emptyList(), null);
170+
XContentBuilder builder = JsonXContent.contentBuilder().prettyPrint();
171+
builder.startObject();
172+
internalStats.doXContentBody(builder, ToXContent.EMPTY_PARAMS);
173+
builder.endObject();
174+
175+
String expected = "{\n" +
176+
" \"count\" : " + count + ",\n" +
177+
" \"min\" : " + min + ",\n" +
178+
" \"max\" : " + max + ",\n" +
179+
" \"avg\" : " + internalStats.getAvg() + ",\n" +
180+
" \"sum\" : " + sum;
181+
if (format != DocValueFormat.RAW) {
182+
expected += ",\n"+
183+
" \"min_as_string\" : \"" + format.format(internalStats.getMin()) + "\",\n" +
184+
" \"max_as_string\" : \"" + format.format(internalStats.getMax()) + "\",\n" +
185+
" \"avg_as_string\" : \"" + format.format(internalStats.getAvg()) + "\",\n" +
186+
" \"sum_as_string\" : \"" + format.format(internalStats.getSum()) + "\"";
187+
}
188+
expected += "\n}";
189+
assertEquals(expected, builder.string());
190+
191+
// count is zero
192+
format = randomNumericDocValueFormat();
193+
min = 0.0;
194+
max = 0.0;
195+
sum = 0.0;
196+
count = 0;
197+
internalStats = createInstance("stats", count, sum, min, max, format, Collections.emptyList(), null);
198+
builder = JsonXContent.contentBuilder().prettyPrint();
199+
builder.startObject();
200+
internalStats.doXContentBody(builder, ToXContent.EMPTY_PARAMS);
201+
builder.endObject();
202+
203+
assertEquals("{\n" +
204+
" \"count\" : 0,\n" +
205+
" \"min\" : null,\n" +
206+
" \"max\" : null,\n" +
207+
" \"avg\" : null,\n" +
208+
" \"sum\" : 0.0\n" +
209+
"}", builder.string());
210+
}
156211
}
157212

0 commit comments

Comments
 (0)