Skip to content

Commit 4562c8a

Browse files
authored
Add parsing for InternalSimpleValue and InternalDerivative (#24162)
1 parent bf5cfab commit 4562c8a

File tree

10 files changed

+183
-14
lines changed

10 files changed

+183
-14
lines changed

core/src/main/java/org/elasticsearch/search/aggregations/metrics/ParsedSingleValueNumericMetricsAggregation.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ protected static double parseValue(XContentParser parser, double defaultNullValu
6363
}
6464
}
6565

66-
protected static void declareSingeValueFields(ObjectParser<? extends ParsedSingleValueNumericMetricsAggregation, Void> objectParser,
66+
protected static void declareSingleValueFields(ObjectParser<? extends ParsedSingleValueNumericMetricsAggregation, Void> objectParser,
6767
double defaultNullValue) {
6868
declareAggregationFields(objectParser);
6969
objectParser.declareField(ParsedSingleValueNumericMetricsAggregation::setValue,

core/src/main/java/org/elasticsearch/search/aggregations/metrics/avg/ParsedAvg.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ protected XContentBuilder doXContentBody(XContentBuilder builder, Params params)
5353
private static final ObjectParser<ParsedAvg, Void> PARSER = new ObjectParser<>(ParsedAvg.class.getSimpleName(), true, ParsedAvg::new);
5454

5555
static {
56-
declareSingeValueFields(PARSER, Double.POSITIVE_INFINITY);
56+
declareSingleValueFields(PARSER, Double.POSITIVE_INFINITY);
5757
}
5858

5959
public static ParsedAvg fromXContent(XContentParser parser, final String name) {

core/src/main/java/org/elasticsearch/search/aggregations/metrics/max/ParsedMax.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ protected XContentBuilder doXContentBody(XContentBuilder builder, Params params)
5151
private static final ObjectParser<ParsedMax, Void> PARSER = new ObjectParser<>(ParsedMax.class.getSimpleName(), true, ParsedMax::new);
5252

5353
static {
54-
declareSingeValueFields(PARSER, Double.NEGATIVE_INFINITY);
54+
declareSingleValueFields(PARSER, Double.NEGATIVE_INFINITY);
5555
}
5656

5757
public static ParsedMax fromXContent(XContentParser parser, final String name) {

core/src/main/java/org/elasticsearch/search/aggregations/metrics/min/ParsedMin.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ protected XContentBuilder doXContentBody(XContentBuilder builder, Params params)
5151
private static final ObjectParser<ParsedMin, Void> PARSER = new ObjectParser<>(ParsedMin.class.getSimpleName(), true, ParsedMin::new);
5252

5353
static {
54-
declareSingeValueFields(PARSER, Double.POSITIVE_INFINITY);
54+
declareSingleValueFields(PARSER, Double.POSITIVE_INFINITY);
5555
}
5656

5757
public static ParsedMin fromXContent(XContentParser parser, final String name) {

core/src/main/java/org/elasticsearch/search/aggregations/metrics/sum/ParsedSum.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ protected XContentBuilder doXContentBody(XContentBuilder builder, Params params)
5050
private static final ObjectParser<ParsedSum, Void> PARSER = new ObjectParser<>(ParsedSum.class.getSimpleName(), true, ParsedSum::new);
5151

5252
static {
53-
declareSingeValueFields(PARSER, Double.NEGATIVE_INFINITY);
53+
declareSingleValueFields(PARSER, Double.NEGATIVE_INFINITY);
5454
}
5555

5656
public static ParsedSum fromXContent(XContentParser parser, final String name) {
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
* Licensed to Elasticsearch under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.elasticsearch.search.aggregations.pipeline;
21+
22+
import org.elasticsearch.common.xcontent.ObjectParser;
23+
import org.elasticsearch.common.xcontent.XContentBuilder;
24+
import org.elasticsearch.common.xcontent.XContentParser;
25+
import org.elasticsearch.search.aggregations.metrics.ParsedSingleValueNumericMetricsAggregation;
26+
27+
import java.io.IOException;
28+
29+
public class ParsedSimpleValue extends ParsedSingleValueNumericMetricsAggregation implements SimpleValue {
30+
31+
@Override
32+
protected String getType() {
33+
return InternalSimpleValue.NAME;
34+
}
35+
36+
private static final ObjectParser<ParsedSimpleValue, Void> PARSER = new ObjectParser<>(ParsedSimpleValue.class.getSimpleName(), true,
37+
ParsedSimpleValue::new);
38+
39+
static {
40+
declareSingleValueFields(PARSER, Double.NaN);
41+
}
42+
43+
public static ParsedSimpleValue fromXContent(XContentParser parser, final String name) {
44+
ParsedSimpleValue simpleValue = PARSER.apply(parser, null);
45+
simpleValue.setName(name);
46+
return simpleValue;
47+
}
48+
49+
@Override
50+
protected XContentBuilder doXContentBody(XContentBuilder builder, Params params) throws IOException {
51+
boolean hasValue = Double.isNaN(value) == false;
52+
builder.field(CommonFields.VALUE.getPreferredName(), hasValue ? value : null);
53+
if (hasValue && valueAsString != null) {
54+
builder.field(CommonFields.VALUE_AS_STRING.getPreferredName(), valueAsString);
55+
}
56+
return builder;
57+
}
58+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/*
2+
* Licensed to Elasticsearch under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.elasticsearch.search.aggregations.pipeline.derivative;
21+
22+
import org.elasticsearch.common.ParseField;
23+
import org.elasticsearch.common.xcontent.ObjectParser;
24+
import org.elasticsearch.common.xcontent.ObjectParser.ValueType;
25+
import org.elasticsearch.common.xcontent.XContentBuilder;
26+
import org.elasticsearch.common.xcontent.XContentParser;
27+
import org.elasticsearch.search.aggregations.pipeline.ParsedSimpleValue;
28+
29+
import java.io.IOException;
30+
31+
public class ParsedDerivative extends ParsedSimpleValue implements Derivative {
32+
33+
private double normalizedValue;
34+
private String normalizedAsString;
35+
private boolean hasNormalizationFactor;
36+
private static final ParseField NORMALIZED_AS_STRING = new ParseField("normalized_value_as_string");
37+
private static final ParseField NORMALIZED = new ParseField("normalized_value");
38+
39+
@Override
40+
public double normalizedValue() {
41+
return this.normalizedValue;
42+
}
43+
44+
@Override
45+
protected String getType() {
46+
return DerivativePipelineAggregationBuilder.NAME;
47+
}
48+
49+
private static final ObjectParser<ParsedDerivative, Void> PARSER = new ObjectParser<>(ParsedDerivative.class.getSimpleName(), true,
50+
ParsedDerivative::new);
51+
52+
static {
53+
declareSingleValueFields(PARSER, Double.NaN);
54+
PARSER.declareField((agg, normalized) -> {
55+
agg.normalizedValue = normalized;
56+
agg.hasNormalizationFactor = true;
57+
}, (parser, context) -> parseValue(parser, Double.NaN), NORMALIZED, ValueType.DOUBLE_OR_NULL);
58+
PARSER.declareString((agg, normalAsString) -> agg.normalizedAsString = normalAsString, NORMALIZED_AS_STRING);
59+
}
60+
61+
public static ParsedDerivative fromXContent(XContentParser parser, final String name) {
62+
ParsedDerivative derivative = PARSER.apply(parser, null);
63+
derivative.setName(name);
64+
return derivative;
65+
}
66+
67+
@Override
68+
protected XContentBuilder doXContentBody(XContentBuilder builder, Params params) throws IOException {
69+
super.doXContentBody(builder, params);
70+
if (hasNormalizationFactor) {
71+
boolean hasValue = Double.isNaN(normalizedValue) == false;
72+
builder.field(NORMALIZED.getPreferredName(), hasValue ? normalizedValue : null);
73+
if (hasValue && normalizedAsString != null) {
74+
builder.field(NORMALIZED_AS_STRING.getPreferredName(), normalizedAsString);
75+
}
76+
}
77+
return builder;
78+
}
79+
}

core/src/test/java/org/elasticsearch/search/aggregations/InternalAggregationTestCase.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,11 @@
5151
import org.elasticsearch.search.aggregations.metrics.sum.SumAggregationBuilder;
5252
import org.elasticsearch.search.aggregations.metrics.valuecount.ParsedValueCount;
5353
import org.elasticsearch.search.aggregations.metrics.valuecount.ValueCountAggregationBuilder;
54+
import org.elasticsearch.search.aggregations.pipeline.InternalSimpleValue;
55+
import org.elasticsearch.search.aggregations.pipeline.ParsedSimpleValue;
5456
import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
57+
import org.elasticsearch.search.aggregations.pipeline.derivative.DerivativePipelineAggregationBuilder;
58+
import org.elasticsearch.search.aggregations.pipeline.derivative.ParsedDerivative;
5559
import org.elasticsearch.test.AbstractWireSerializingTestCase;
5660

5761
import java.io.IOException;
@@ -85,6 +89,8 @@ static List<NamedXContentRegistry.Entry> getNamedXContents() {
8589
namedXContents.put(SumAggregationBuilder.NAME, (p, c) -> ParsedSum.fromXContent(p, (String) c));
8690
namedXContents.put(AvgAggregationBuilder.NAME, (p, c) -> ParsedAvg.fromXContent(p, (String) c));
8791
namedXContents.put(ValueCountAggregationBuilder.NAME, (p, c) -> ParsedValueCount.fromXContent(p, (String) c));
92+
namedXContents.put(InternalSimpleValue.NAME, (p, c) -> ParsedSimpleValue.fromXContent(p, (String) c));
93+
namedXContents.put(DerivativePipelineAggregationBuilder.NAME, (p, c) -> ParsedDerivative.fromXContent(p, (String) c));
8894

8995
return namedXContents.entrySet().stream()
9096
.map(entry -> new NamedXContentRegistry.Entry(Aggregation.class, new ParseField(entry.getKey()), entry.getValue()))

core/src/test/java/org/elasticsearch/search/aggregations/pipeline/InternalSimpleValueTests.java

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import org.elasticsearch.common.io.stream.Writeable.Reader;
2323
import org.elasticsearch.search.DocValueFormat;
2424
import org.elasticsearch.search.aggregations.InternalAggregationTestCase;
25+
import org.elasticsearch.search.aggregations.ParsedAggregation;
2526

2627
import java.util.Collections;
2728
import java.util.List;
@@ -30,18 +31,18 @@
3031
public class InternalSimpleValueTests extends InternalAggregationTestCase<InternalSimpleValue>{
3132

3233
@Override
33-
protected InternalSimpleValue createTestInstance(String name,
34-
List<PipelineAggregator> pipelineAggregators, Map<String, Object> metaData) {
34+
protected InternalSimpleValue createTestInstance(String name, List<PipelineAggregator> pipelineAggregators,
35+
Map<String, Object> metaData) {
3536
DocValueFormat formatter = randomNumericDocValueFormat();
36-
double value = randomDoubleBetween(0, 100000, true);
37+
double value = frequently() ? randomDoubleBetween(0, 100000, true)
38+
: randomFrom(new Double[] { Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, Double.NaN });
3739
return new InternalSimpleValue(name, value, formatter, pipelineAggregators, metaData);
3840
}
3941

4042
@Override
4143
public void testReduceRandom() {
4244
expectThrows(UnsupportedOperationException.class,
43-
() -> createTestInstance("name", Collections.emptyList(), null).reduce(null,
44-
null));
45+
() -> createTestInstance("name", Collections.emptyList(), null).reduce(null, null));
4546
}
4647

4748
@Override
@@ -54,4 +55,16 @@ protected Reader<InternalSimpleValue> instanceReader() {
5455
return InternalSimpleValue::new;
5556
}
5657

58+
@Override
59+
protected void assertFromXContent(InternalSimpleValue simpleValue, ParsedAggregation parsedAggregation) {
60+
ParsedSimpleValue parsed = ((ParsedSimpleValue) parsedAggregation);
61+
if (Double.isInfinite(simpleValue.getValue()) == false && Double.isNaN(simpleValue.getValue()) == false) {
62+
assertEquals(simpleValue.getValue(), parsed.value(), 0);
63+
assertEquals(simpleValue.getValueAsString(), parsed.getValueAsString());
64+
} else {
65+
// we write Double.NEGATIVE_INFINITY, Double.POSITIVE amd Double.NAN to xContent as 'null', so we
66+
// cannot differentiate between them. Also we cannot recreate the exact String representation
67+
assertEquals(parsed.value(), Double.NaN, 0);
68+
}
69+
}
5770
}

core/src/test/java/org/elasticsearch/search/aggregations/pipeline/derivative/InternalDerivativeTests.java

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import org.elasticsearch.common.io.stream.Writeable.Reader;
2323
import org.elasticsearch.search.DocValueFormat;
2424
import org.elasticsearch.search.aggregations.InternalAggregationTestCase;
25+
import org.elasticsearch.search.aggregations.ParsedAggregation;
2526
import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
2627

2728
import java.util.Collections;
@@ -34,16 +35,16 @@ public class InternalDerivativeTests extends InternalAggregationTestCase<Interna
3435
protected InternalDerivative createTestInstance(String name,
3536
List<PipelineAggregator> pipelineAggregators, Map<String, Object> metaData) {
3637
DocValueFormat formatter = randomNumericDocValueFormat();
37-
double value = randomDoubleBetween(0, 100000, true);
38-
double normalizationFactor = randomDoubleBetween(0, 100000, true);
38+
double value = frequently() ? randomDoubleBetween(-100000, 100000, true)
39+
: randomFrom(new Double[] { Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, Double.NaN });
40+
double normalizationFactor = frequently() ? randomDoubleBetween(0, 100000, true) : 0;
3941
return new InternalDerivative(name, value, normalizationFactor, formatter, pipelineAggregators, metaData);
4042
}
4143

4244
@Override
4345
public void testReduceRandom() {
4446
expectThrows(UnsupportedOperationException.class,
45-
() -> createTestInstance("name", Collections.emptyList(), null).reduce(null,
46-
null));
47+
() -> createTestInstance("name", Collections.emptyList(), null).reduce(null, null));
4748
}
4849

4950
@Override
@@ -56,4 +57,16 @@ protected Reader<InternalDerivative> instanceReader() {
5657
return InternalDerivative::new;
5758
}
5859

60+
@Override
61+
protected void assertFromXContent(InternalDerivative derivative, ParsedAggregation parsedAggregation) {
62+
ParsedDerivative parsed = ((ParsedDerivative) parsedAggregation);
63+
if (Double.isInfinite(derivative.getValue()) == false && Double.isNaN(derivative.getValue()) == false) {
64+
assertEquals(derivative.getValue(), parsed.value(), Double.MIN_VALUE);
65+
assertEquals(derivative.getValueAsString(), parsed.getValueAsString());
66+
} else {
67+
// we write Double.NEGATIVE_INFINITY, Double.POSITIVE amd Double.NAN to xContent as 'null', so we
68+
// cannot differentiate between them. Also we cannot recreate the exact String representation
69+
assertEquals(parsed.value(), Double.NaN, Double.MIN_VALUE);
70+
}
71+
}
5972
}

0 commit comments

Comments
 (0)