Skip to content

Commit 3fab63a

Browse files
not-napoleonimotovelasticmachine
authored
Use Decimal formatter for Numeric ValuesSourceTypes (#54366)
Co-authored-by: Igor Motov <[email protected]> Co-authored-by: Elastic Machine <[email protected]>
1 parent 7a039aa commit 3fab63a

File tree

2 files changed

+36
-0
lines changed

2 files changed

+36
-0
lines changed

server/src/main/java/org/elasticsearch/search/aggregations/support/CoreValuesSourceType.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,22 @@ public ValuesSource replaceMissing(ValuesSource valuesSource, Object rawMissing,
7575
Number missing = docValueFormat.parseDouble(rawMissing.toString(), false, nowSupplier);
7676
return MissingValues.replaceMissing((ValuesSource.Numeric) valuesSource, missing);
7777
}
78+
79+
@Override
80+
public DocValueFormat getFormatter(String format, ZoneId tz) {
81+
/* TODO: this silently ignores a timezone argument, whereas NumberFieldType#docValueFormat throws if given a time zone.
82+
Before we can solve this, we need to resolve https://github.com/elastic/elasticsearch/issues/47469 which deals
83+
with the fact that the same formatter is used for input and output values. We want to support a use case in SQL
84+
(and elsewhere) that allows for passing a long value milliseconds since epoch into date aggregations. In that case,
85+
the timezone is sensible as part of the bucket key format.
86+
*/
87+
if (format == null) {
88+
return DocValueFormat.RAW;
89+
} else {
90+
return new DocValueFormat.Decimal(format);
91+
}
92+
93+
}
7894
},
7995
BYTES() {
8096
@Override

server/src/test/java/org/elasticsearch/search/aggregations/metrics/WeightedAvgAggregatorTests.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,26 @@ public void testMultiWeight() throws IOException {
354354
"Use a script to combine multiple weights-per-doc into a single value."));
355355
}
356356

357+
public void testFormatter() throws IOException {
358+
MultiValuesSourceFieldConfig valueConfig = new MultiValuesSourceFieldConfig.Builder().setFieldName("value_field").build();
359+
MultiValuesSourceFieldConfig weightConfig = new MultiValuesSourceFieldConfig.Builder().setFieldName("weight_field").build();
360+
WeightedAvgAggregationBuilder aggregationBuilder = new WeightedAvgAggregationBuilder("_name")
361+
.value(valueConfig)
362+
.weight(weightConfig)
363+
.format("0.00%");
364+
testCase(new MatchAllDocsQuery(), aggregationBuilder, iw -> {
365+
iw.addDocument(Arrays.asList(new SortedNumericDocValuesField("value_field", 7),
366+
new SortedNumericDocValuesField("weight_field", 1)));
367+
iw.addDocument(Arrays.asList(new SortedNumericDocValuesField("value_field", 2),
368+
new SortedNumericDocValuesField("weight_field", 1)));
369+
iw.addDocument(Arrays.asList(new SortedNumericDocValuesField("value_field", 3),
370+
new SortedNumericDocValuesField("weight_field", 1)));
371+
}, avg -> {
372+
assertEquals(4, avg.getValue(), 0);
373+
assertTrue(AggregationInspectionHelper.hasValue(avg));
374+
assertEquals("400.00%", avg.getValueAsString());
375+
});
376+
}
357377

358378
public void testSummationAccuracy() throws IOException {
359379
// Summing up a normal array and expect an accurate value

0 commit comments

Comments
 (0)