From f9790d468c73a3afad7798de38a80db50c282cb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20B=C3=BCscher?= Date: Tue, 4 Apr 2017 11:55:47 +0200 Subject: [PATCH] Add parsing to InternalCardinality --- .../aggregations/InternalAggregation.java | 6 +++ .../cardinality/InternalCardinality.java | 39 ++++++++++++++++++- .../cardinality/InternalCardinalityTests.java | 35 +++++++++++++++++ 3 files changed, 78 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/org/elasticsearch/search/aggregations/InternalAggregation.java b/core/src/main/java/org/elasticsearch/search/aggregations/InternalAggregation.java index 4fb6a434c84d3..48d73206364b6 100644 --- a/core/src/main/java/org/elasticsearch/search/aggregations/InternalAggregation.java +++ b/core/src/main/java/org/elasticsearch/search/aggregations/InternalAggregation.java @@ -23,6 +23,7 @@ import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.util.BigArrays; +import org.elasticsearch.common.xcontent.AbstractObjectParser; import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.rest.action.search.RestSearchAction; @@ -193,6 +194,11 @@ public final XContentBuilder toXContent(XContentBuilder builder, Params params) return builder; } + protected static void declareCommonField(AbstractObjectParser, Void> parser) { + parser.declareObject((map, metaMap) -> map.put(CommonFields.META.getPreferredName(), metaMap), + (p, c) -> p.map(), CommonFields.META); + } + public abstract XContentBuilder doXContentBody(XContentBuilder builder, Params params) throws IOException; @Override diff --git a/core/src/main/java/org/elasticsearch/search/aggregations/metrics/cardinality/InternalCardinality.java b/core/src/main/java/org/elasticsearch/search/aggregations/metrics/cardinality/InternalCardinality.java index 028e97a69ff82..0297d742de3ba 100644 --- a/core/src/main/java/org/elasticsearch/search/aggregations/metrics/cardinality/InternalCardinality.java +++ b/core/src/main/java/org/elasticsearch/search/aggregations/metrics/cardinality/InternalCardinality.java @@ -22,18 +22,23 @@ import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.util.BigArrays; +import org.elasticsearch.common.xcontent.ObjectParser; import org.elasticsearch.common.xcontent.XContentBuilder; +import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.search.DocValueFormat; import org.elasticsearch.search.aggregations.InternalAggregation; import org.elasticsearch.search.aggregations.metrics.InternalNumericMetricsAggregation; import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator; import java.io.IOException; +import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Map; -public final class InternalCardinality extends InternalNumericMetricsAggregation.SingleValue implements Cardinality { +public class InternalCardinality extends InternalNumericMetricsAggregation.SingleValue implements Cardinality { private final HyperLogLogPlusPlus counts; + transient private Long cardinalityValue; InternalCardinality(String name, HyperLogLogPlusPlus counts, List pipelineAggregators, Map metaData) { @@ -41,6 +46,13 @@ public final class InternalCardinality extends InternalNumericMetricsAggregation this.counts = counts; } + private InternalCardinality(String name, long cardinalityValue, List pipelineAggregators, + Map metaData) { + super(name, pipelineAggregators, metaData); + this.counts = null; + this.cardinalityValue = cardinalityValue; + } + /** * Read from a stream. */ @@ -77,9 +89,14 @@ public double value() { @Override public long getValue() { - return counts == null ? 0 : counts.cardinality(0); + if (cardinalityValue == null) { + cardinalityValue = counts == null ? 0 : counts.cardinality(0); + } + return cardinalityValue; } + + @Override public InternalAggregation doReduce(List aggregations, ReduceContext reduceContext) { InternalCardinality reduced = null; @@ -127,4 +144,22 @@ protected boolean doEquals(Object obj) { HyperLogLogPlusPlus getState() { return counts; } + private static final ObjectParser, Void> PARSER = new ObjectParser<>( + "internal_cardinality", true, () -> new HashMap<>()); + + static { + declareCommonField(PARSER); + PARSER.declareLong((map, value) -> map.put(CommonFields.VALUE.getPreferredName(), value), + CommonFields.VALUE); + } + + public static InternalCardinality parseXContentBody(final String name, XContentParser parser) { + Map map = PARSER.apply(parser, null); + final long cardinalityValue = (Long) map.getOrDefault(CommonFields.VALUE.getPreferredName(), + Double.POSITIVE_INFINITY); + @SuppressWarnings("unchecked") + final Map metaData = (Map) map + .get(CommonFields.META.getPreferredName()); + return new InternalCardinality(name, cardinalityValue, Collections.emptyList(), metaData); + } } diff --git a/core/src/test/java/org/elasticsearch/search/aggregations/metrics/cardinality/InternalCardinalityTests.java b/core/src/test/java/org/elasticsearch/search/aggregations/metrics/cardinality/InternalCardinalityTests.java index 7c5809f323bdf..fdd60766704a4 100644 --- a/core/src/test/java/org/elasticsearch/search/aggregations/metrics/cardinality/InternalCardinalityTests.java +++ b/core/src/test/java/org/elasticsearch/search/aggregations/metrics/cardinality/InternalCardinalityTests.java @@ -19,20 +19,30 @@ package org.elasticsearch.search.aggregations.metrics.cardinality; +import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.io.stream.Writeable.Reader; import org.elasticsearch.common.lease.Releasables; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.util.MockBigArrays; +import org.elasticsearch.common.xcontent.ToXContent; +import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.common.xcontent.XContentType; import org.elasticsearch.indices.breaker.NoneCircuitBreakerService; +import org.elasticsearch.rest.action.search.RestSearchAction; import org.elasticsearch.search.aggregations.InternalAggregationTestCase; import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator; import org.junit.After; import org.junit.Before; +import java.io.IOException; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Map; +import static org.elasticsearch.common.xcontent.XContentHelper.toXContent; +import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertToXContentEquivalent; + public class InternalCardinalityTests extends InternalAggregationTestCase { private static List algos; private static int p; @@ -73,6 +83,31 @@ protected void assertReduced(InternalCardinality reduced, List