Add parsing for InternalSimpleValue and InternalDerivative (#24162)
This commit is contained in:
parent
bf5cfabe04
commit
4562c8a345
|
@ -63,7 +63,7 @@ public abstract class ParsedSingleValueNumericMetricsAggregation extends ParsedA
|
|||
}
|
||||
}
|
||||
|
||||
protected static void declareSingeValueFields(ObjectParser<? extends ParsedSingleValueNumericMetricsAggregation, Void> objectParser,
|
||||
protected static void declareSingleValueFields(ObjectParser<? extends ParsedSingleValueNumericMetricsAggregation, Void> objectParser,
|
||||
double defaultNullValue) {
|
||||
declareAggregationFields(objectParser);
|
||||
objectParser.declareField(ParsedSingleValueNumericMetricsAggregation::setValue,
|
||||
|
|
|
@ -53,7 +53,7 @@ public class ParsedAvg extends ParsedSingleValueNumericMetricsAggregation implem
|
|||
private static final ObjectParser<ParsedAvg, Void> PARSER = new ObjectParser<>(ParsedAvg.class.getSimpleName(), true, ParsedAvg::new);
|
||||
|
||||
static {
|
||||
declareSingeValueFields(PARSER, Double.POSITIVE_INFINITY);
|
||||
declareSingleValueFields(PARSER, Double.POSITIVE_INFINITY);
|
||||
}
|
||||
|
||||
public static ParsedAvg fromXContent(XContentParser parser, final String name) {
|
||||
|
|
|
@ -51,7 +51,7 @@ public class ParsedMax extends ParsedSingleValueNumericMetricsAggregation implem
|
|||
private static final ObjectParser<ParsedMax, Void> PARSER = new ObjectParser<>(ParsedMax.class.getSimpleName(), true, ParsedMax::new);
|
||||
|
||||
static {
|
||||
declareSingeValueFields(PARSER, Double.NEGATIVE_INFINITY);
|
||||
declareSingleValueFields(PARSER, Double.NEGATIVE_INFINITY);
|
||||
}
|
||||
|
||||
public static ParsedMax fromXContent(XContentParser parser, final String name) {
|
||||
|
|
|
@ -51,7 +51,7 @@ public class ParsedMin extends ParsedSingleValueNumericMetricsAggregation implem
|
|||
private static final ObjectParser<ParsedMin, Void> PARSER = new ObjectParser<>(ParsedMin.class.getSimpleName(), true, ParsedMin::new);
|
||||
|
||||
static {
|
||||
declareSingeValueFields(PARSER, Double.POSITIVE_INFINITY);
|
||||
declareSingleValueFields(PARSER, Double.POSITIVE_INFINITY);
|
||||
}
|
||||
|
||||
public static ParsedMin fromXContent(XContentParser parser, final String name) {
|
||||
|
|
|
@ -50,7 +50,7 @@ public class ParsedSum extends ParsedSingleValueNumericMetricsAggregation implem
|
|||
private static final ObjectParser<ParsedSum, Void> PARSER = new ObjectParser<>(ParsedSum.class.getSimpleName(), true, ParsedSum::new);
|
||||
|
||||
static {
|
||||
declareSingeValueFields(PARSER, Double.NEGATIVE_INFINITY);
|
||||
declareSingleValueFields(PARSER, Double.NEGATIVE_INFINITY);
|
||||
}
|
||||
|
||||
public static ParsedSum fromXContent(XContentParser parser, final String name) {
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.search.aggregations.pipeline;
|
||||
|
||||
import org.elasticsearch.common.xcontent.ObjectParser;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.search.aggregations.metrics.ParsedSingleValueNumericMetricsAggregation;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class ParsedSimpleValue extends ParsedSingleValueNumericMetricsAggregation implements SimpleValue {
|
||||
|
||||
@Override
|
||||
protected String getType() {
|
||||
return InternalSimpleValue.NAME;
|
||||
}
|
||||
|
||||
private static final ObjectParser<ParsedSimpleValue, Void> PARSER = new ObjectParser<>(ParsedSimpleValue.class.getSimpleName(), true,
|
||||
ParsedSimpleValue::new);
|
||||
|
||||
static {
|
||||
declareSingleValueFields(PARSER, Double.NaN);
|
||||
}
|
||||
|
||||
public static ParsedSimpleValue fromXContent(XContentParser parser, final String name) {
|
||||
ParsedSimpleValue simpleValue = PARSER.apply(parser, null);
|
||||
simpleValue.setName(name);
|
||||
return simpleValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected XContentBuilder doXContentBody(XContentBuilder builder, Params params) throws IOException {
|
||||
boolean hasValue = Double.isNaN(value) == false;
|
||||
builder.field(CommonFields.VALUE.getPreferredName(), hasValue ? value : null);
|
||||
if (hasValue && valueAsString != null) {
|
||||
builder.field(CommonFields.VALUE_AS_STRING.getPreferredName(), valueAsString);
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.search.aggregations.pipeline.derivative;
|
||||
|
||||
import org.elasticsearch.common.ParseField;
|
||||
import org.elasticsearch.common.xcontent.ObjectParser;
|
||||
import org.elasticsearch.common.xcontent.ObjectParser.ValueType;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.search.aggregations.pipeline.ParsedSimpleValue;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class ParsedDerivative extends ParsedSimpleValue implements Derivative {
|
||||
|
||||
private double normalizedValue;
|
||||
private String normalizedAsString;
|
||||
private boolean hasNormalizationFactor;
|
||||
private static final ParseField NORMALIZED_AS_STRING = new ParseField("normalized_value_as_string");
|
||||
private static final ParseField NORMALIZED = new ParseField("normalized_value");
|
||||
|
||||
@Override
|
||||
public double normalizedValue() {
|
||||
return this.normalizedValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getType() {
|
||||
return DerivativePipelineAggregationBuilder.NAME;
|
||||
}
|
||||
|
||||
private static final ObjectParser<ParsedDerivative, Void> PARSER = new ObjectParser<>(ParsedDerivative.class.getSimpleName(), true,
|
||||
ParsedDerivative::new);
|
||||
|
||||
static {
|
||||
declareSingleValueFields(PARSER, Double.NaN);
|
||||
PARSER.declareField((agg, normalized) -> {
|
||||
agg.normalizedValue = normalized;
|
||||
agg.hasNormalizationFactor = true;
|
||||
}, (parser, context) -> parseValue(parser, Double.NaN), NORMALIZED, ValueType.DOUBLE_OR_NULL);
|
||||
PARSER.declareString((agg, normalAsString) -> agg.normalizedAsString = normalAsString, NORMALIZED_AS_STRING);
|
||||
}
|
||||
|
||||
public static ParsedDerivative fromXContent(XContentParser parser, final String name) {
|
||||
ParsedDerivative derivative = PARSER.apply(parser, null);
|
||||
derivative.setName(name);
|
||||
return derivative;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected XContentBuilder doXContentBody(XContentBuilder builder, Params params) throws IOException {
|
||||
super.doXContentBody(builder, params);
|
||||
if (hasNormalizationFactor) {
|
||||
boolean hasValue = Double.isNaN(normalizedValue) == false;
|
||||
builder.field(NORMALIZED.getPreferredName(), hasValue ? normalizedValue : null);
|
||||
if (hasValue && normalizedAsString != null) {
|
||||
builder.field(NORMALIZED_AS_STRING.getPreferredName(), normalizedAsString);
|
||||
}
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
}
|
|
@ -51,7 +51,11 @@ import org.elasticsearch.search.aggregations.metrics.sum.ParsedSum;
|
|||
import org.elasticsearch.search.aggregations.metrics.sum.SumAggregationBuilder;
|
||||
import org.elasticsearch.search.aggregations.metrics.valuecount.ParsedValueCount;
|
||||
import org.elasticsearch.search.aggregations.metrics.valuecount.ValueCountAggregationBuilder;
|
||||
import org.elasticsearch.search.aggregations.pipeline.InternalSimpleValue;
|
||||
import org.elasticsearch.search.aggregations.pipeline.ParsedSimpleValue;
|
||||
import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
|
||||
import org.elasticsearch.search.aggregations.pipeline.derivative.DerivativePipelineAggregationBuilder;
|
||||
import org.elasticsearch.search.aggregations.pipeline.derivative.ParsedDerivative;
|
||||
import org.elasticsearch.test.AbstractWireSerializingTestCase;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -85,6 +89,8 @@ public abstract class InternalAggregationTestCase<T extends InternalAggregation>
|
|||
namedXContents.put(SumAggregationBuilder.NAME, (p, c) -> ParsedSum.fromXContent(p, (String) c));
|
||||
namedXContents.put(AvgAggregationBuilder.NAME, (p, c) -> ParsedAvg.fromXContent(p, (String) c));
|
||||
namedXContents.put(ValueCountAggregationBuilder.NAME, (p, c) -> ParsedValueCount.fromXContent(p, (String) c));
|
||||
namedXContents.put(InternalSimpleValue.NAME, (p, c) -> ParsedSimpleValue.fromXContent(p, (String) c));
|
||||
namedXContents.put(DerivativePipelineAggregationBuilder.NAME, (p, c) -> ParsedDerivative.fromXContent(p, (String) c));
|
||||
|
||||
return namedXContents.entrySet().stream()
|
||||
.map(entry -> new NamedXContentRegistry.Entry(Aggregation.class, new ParseField(entry.getKey()), entry.getValue()))
|
||||
|
|
|
@ -22,6 +22,7 @@ package org.elasticsearch.search.aggregations.pipeline;
|
|||
import org.elasticsearch.common.io.stream.Writeable.Reader;
|
||||
import org.elasticsearch.search.DocValueFormat;
|
||||
import org.elasticsearch.search.aggregations.InternalAggregationTestCase;
|
||||
import org.elasticsearch.search.aggregations.ParsedAggregation;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
@ -30,18 +31,18 @@ import java.util.Map;
|
|||
public class InternalSimpleValueTests extends InternalAggregationTestCase<InternalSimpleValue>{
|
||||
|
||||
@Override
|
||||
protected InternalSimpleValue createTestInstance(String name,
|
||||
List<PipelineAggregator> pipelineAggregators, Map<String, Object> metaData) {
|
||||
protected InternalSimpleValue createTestInstance(String name, List<PipelineAggregator> pipelineAggregators,
|
||||
Map<String, Object> metaData) {
|
||||
DocValueFormat formatter = randomNumericDocValueFormat();
|
||||
double value = randomDoubleBetween(0, 100000, true);
|
||||
double value = frequently() ? randomDoubleBetween(0, 100000, true)
|
||||
: randomFrom(new Double[] { Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, Double.NaN });
|
||||
return new InternalSimpleValue(name, value, formatter, pipelineAggregators, metaData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void testReduceRandom() {
|
||||
expectThrows(UnsupportedOperationException.class,
|
||||
() -> createTestInstance("name", Collections.emptyList(), null).reduce(null,
|
||||
null));
|
||||
() -> createTestInstance("name", Collections.emptyList(), null).reduce(null, null));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -54,4 +55,16 @@ public class InternalSimpleValueTests extends InternalAggregationTestCase<Intern
|
|||
return InternalSimpleValue::new;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void assertFromXContent(InternalSimpleValue simpleValue, ParsedAggregation parsedAggregation) {
|
||||
ParsedSimpleValue parsed = ((ParsedSimpleValue) parsedAggregation);
|
||||
if (Double.isInfinite(simpleValue.getValue()) == false && Double.isNaN(simpleValue.getValue()) == false) {
|
||||
assertEquals(simpleValue.getValue(), parsed.value(), 0);
|
||||
assertEquals(simpleValue.getValueAsString(), parsed.getValueAsString());
|
||||
} else {
|
||||
// we write Double.NEGATIVE_INFINITY, Double.POSITIVE amd Double.NAN to xContent as 'null', so we
|
||||
// cannot differentiate between them. Also we cannot recreate the exact String representation
|
||||
assertEquals(parsed.value(), Double.NaN, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ package org.elasticsearch.search.aggregations.pipeline.derivative;
|
|||
import org.elasticsearch.common.io.stream.Writeable.Reader;
|
||||
import org.elasticsearch.search.DocValueFormat;
|
||||
import org.elasticsearch.search.aggregations.InternalAggregationTestCase;
|
||||
import org.elasticsearch.search.aggregations.ParsedAggregation;
|
||||
import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
|
||||
|
||||
import java.util.Collections;
|
||||
|
@ -34,16 +35,16 @@ public class InternalDerivativeTests extends InternalAggregationTestCase<Interna
|
|||
protected InternalDerivative createTestInstance(String name,
|
||||
List<PipelineAggregator> pipelineAggregators, Map<String, Object> metaData) {
|
||||
DocValueFormat formatter = randomNumericDocValueFormat();
|
||||
double value = randomDoubleBetween(0, 100000, true);
|
||||
double normalizationFactor = randomDoubleBetween(0, 100000, true);
|
||||
double value = frequently() ? randomDoubleBetween(-100000, 100000, true)
|
||||
: randomFrom(new Double[] { Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, Double.NaN });
|
||||
double normalizationFactor = frequently() ? randomDoubleBetween(0, 100000, true) : 0;
|
||||
return new InternalDerivative(name, value, normalizationFactor, formatter, pipelineAggregators, metaData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void testReduceRandom() {
|
||||
expectThrows(UnsupportedOperationException.class,
|
||||
() -> createTestInstance("name", Collections.emptyList(), null).reduce(null,
|
||||
null));
|
||||
() -> createTestInstance("name", Collections.emptyList(), null).reduce(null, null));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -56,4 +57,16 @@ public class InternalDerivativeTests extends InternalAggregationTestCase<Interna
|
|||
return InternalDerivative::new;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void assertFromXContent(InternalDerivative derivative, ParsedAggregation parsedAggregation) {
|
||||
ParsedDerivative parsed = ((ParsedDerivative) parsedAggregation);
|
||||
if (Double.isInfinite(derivative.getValue()) == false && Double.isNaN(derivative.getValue()) == false) {
|
||||
assertEquals(derivative.getValue(), parsed.value(), Double.MIN_VALUE);
|
||||
assertEquals(derivative.getValueAsString(), parsed.getValueAsString());
|
||||
} else {
|
||||
// we write Double.NEGATIVE_INFINITY, Double.POSITIVE amd Double.NAN to xContent as 'null', so we
|
||||
// cannot differentiate between them. Also we cannot recreate the exact String representation
|
||||
assertEquals(parsed.value(), Double.NaN, Double.MIN_VALUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue