diff --git a/core/src/main/java/org/elasticsearch/search/aggregations/ParsedAggregation.java b/core/src/main/java/org/elasticsearch/search/aggregations/ParsedAggregation.java index 92cbe302296..ae620ba601e 100644 --- a/core/src/main/java/org/elasticsearch/search/aggregations/ParsedAggregation.java +++ b/core/src/main/java/org/elasticsearch/search/aggregations/ParsedAggregation.java @@ -38,7 +38,7 @@ public abstract class ParsedAggregation implements Aggregation, ToXContent { (parser, context) -> parser.map(), InternalAggregation.CommonFields.META); } - String name; + private String name; Map metadata; @Override @@ -46,6 +46,10 @@ public abstract class ParsedAggregation implements Aggregation, ToXContent { return name; } + protected void setName(String name) { + this.name = name; + } + @Override public final Map getMetaData() { return metadata; @@ -59,6 +63,7 @@ public abstract class ParsedAggregation implements Aggregation, ToXContent { //TODO it may make sense to move getType to the Aggregation interface given that we are duplicating it in both implementations protected abstract String getType(); + @Override public XContentBuilder toXContent(XContentBuilder builder, ToXContent.Params params) throws IOException { // Concatenates the type and the name of the aggregation (ex: top_hits#foo) builder.startObject(String.join(InternalAggregation.TYPED_KEYS_DELIMITER, getType(), name)); @@ -72,4 +77,4 @@ public abstract class ParsedAggregation implements Aggregation, ToXContent { } protected abstract XContentBuilder doXContentBody(XContentBuilder builder, Params params) throws IOException; -} +} \ No newline at end of file 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 028e97a69ff..ce1e9fc8939 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 @@ -128,3 +128,4 @@ public final class InternalCardinality extends InternalNumericMetricsAggregation return counts; } } + diff --git a/core/src/main/java/org/elasticsearch/search/aggregations/metrics/cardinality/ParsedCardinality.java b/core/src/main/java/org/elasticsearch/search/aggregations/metrics/cardinality/ParsedCardinality.java new file mode 100644 index 00000000000..58f24953aac --- /dev/null +++ b/core/src/main/java/org/elasticsearch/search/aggregations/metrics/cardinality/ParsedCardinality.java @@ -0,0 +1,80 @@ +/* + * 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.metrics.cardinality; + +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.ParsedAggregation; + +import java.io.IOException; + +public class ParsedCardinality extends ParsedAggregation implements Cardinality { + + private long cardinalityValue; + + @Override + public String getValueAsString() { + // InternalCardinality doesn't print "value_as_string", but you can get a formated value using + // getValueAsString(). That method uses the raw formatter so we also use it here. + return DocValueFormat.RAW.format((double) cardinalityValue); + } + + @Override + public double value() { + return getValue(); + } + + @Override + public long getValue() { + return cardinalityValue; + } + + private void setValue(long cardinalityValue) { + this.cardinalityValue = cardinalityValue; + } + + @Override + protected String getType() { + return CardinalityAggregationBuilder.NAME; + } + + private static final ObjectParser PARSER = new ObjectParser<>( + CardinalityAggregationBuilder.NAME, true, ParsedCardinality::new); + + static { + declareCommonFields(PARSER); + PARSER.declareLong(ParsedCardinality::setValue, CommonFields.VALUE); + } + + public static ParsedCardinality fromXContent(XContentParser parser, final String name) { + ParsedCardinality cardinality = PARSER.apply(parser, null); + cardinality.setName(name); + return cardinality; + } + + @Override + protected XContentBuilder doXContentBody(XContentBuilder builder, Params params) + throws IOException { + builder.field(CommonFields.VALUE.getPreferredName(), cardinalityValue); + return builder; + } +} \ No newline at end of file diff --git a/core/src/test/java/org/elasticsearch/search/aggregations/InternalAggregationTestCase.java b/core/src/test/java/org/elasticsearch/search/aggregations/InternalAggregationTestCase.java index f899fde087c..1f0e9d2d74f 100644 --- a/core/src/test/java/org/elasticsearch/search/aggregations/InternalAggregationTestCase.java +++ b/core/src/test/java/org/elasticsearch/search/aggregations/InternalAggregationTestCase.java @@ -98,10 +98,13 @@ public abstract class InternalAggregationTestCase private T createTestInstance(String name) { List pipelineAggregators = new ArrayList<>(); // TODO populate pipelineAggregators - Map metaData = new HashMap<>(); - int metaDataCount = randomBoolean() ? 0 : between(1, 10); - while (metaData.size() < metaDataCount) { - metaData.put(randomAlphaOfLength(5), randomAlphaOfLength(5)); + Map metaData = null; + if (randomBoolean()) { + metaData = new HashMap<>(); + int metaDataCount = between(0, 10); + while (metaData.size() < metaDataCount) { + metaData.put(randomAlphaOfLength(5), randomAlphaOfLength(5)); + } } return createTestInstance(name, pipelineAggregators, metaData); } diff --git a/core/src/test/java/org/elasticsearch/search/aggregations/ParsedAggregationTests.java b/core/src/test/java/org/elasticsearch/search/aggregations/ParsedAggregationTests.java index f4015ca8d6b..a79ccf5c91f 100644 --- a/core/src/test/java/org/elasticsearch/search/aggregations/ParsedAggregationTests.java +++ b/core/src/test/java/org/elasticsearch/search/aggregations/ParsedAggregationTests.java @@ -105,7 +105,7 @@ public class ParsedAggregationTests extends ESTestCase { public static TestParsedAggregation fromXContent(XContentParser parser, String name) throws IOException { TestParsedAggregation parsedAgg = PARSER.parse(parser, null); - parsedAgg.name = name; + parsedAgg.setName(name); return parsedAgg; } } 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 7c5809f323b..83b9dfbe46e 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,33 @@ package org.elasticsearch.search.aggregations.metrics.cardinality; +import org.elasticsearch.common.ParseField; +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.NamedXContentRegistry; +import org.elasticsearch.common.xcontent.ToXContent; +import org.elasticsearch.common.xcontent.XContentHelper; +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.Aggregation; 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.test.hamcrest.ElasticsearchAssertions.assertToXContentEquivalent; + public class InternalCardinalityTests extends InternalAggregationTestCase { private static List algos; private static int p; @@ -73,6 +86,41 @@ public class InternalCardinalityTests extends InternalAggregationTestCase ParsedCardinality.fromXContent(parser, (String) name)); + return new NamedXContentRegistry(Collections.singletonList(entry)); + } + @After public void cleanup() { Releasables.close(algos);