From 055875392edcdb7e8b06688575de28a8eca25cbc Mon Sep 17 00:00:00 2001 From: Tanguy Leroux Date: Thu, 18 May 2017 09:37:46 +0200 Subject: [PATCH] Add parsing method for Top Hits aggregation (#24717) Related to #23331 --- .../metrics/tophits/ParsedTopHits.java | 63 +++++++++++++++++++ .../aggregations/AggregationsTests.java | 2 + .../metrics/tophits/InternalTopHitsTests.java | 42 ++++++++++++- .../test/InternalAggregationTestCase.java | 3 + 4 files changed, 108 insertions(+), 2 deletions(-) create mode 100644 core/src/main/java/org/elasticsearch/search/aggregations/metrics/tophits/ParsedTopHits.java diff --git a/core/src/main/java/org/elasticsearch/search/aggregations/metrics/tophits/ParsedTopHits.java b/core/src/main/java/org/elasticsearch/search/aggregations/metrics/tophits/ParsedTopHits.java new file mode 100644 index 00000000000..362423abca8 --- /dev/null +++ b/core/src/main/java/org/elasticsearch/search/aggregations/metrics/tophits/ParsedTopHits.java @@ -0,0 +1,63 @@ +/* + * 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.tophits; + +import org.elasticsearch.common.ParseField; +import org.elasticsearch.common.xcontent.ObjectParser; +import org.elasticsearch.common.xcontent.XContentBuilder; +import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.search.SearchHits; +import org.elasticsearch.search.aggregations.ParsedAggregation; + +import java.io.IOException; + +public class ParsedTopHits extends ParsedAggregation implements TopHits { + + private SearchHits searchHits; + + @Override + public String getType() { + return TopHitsAggregationBuilder.NAME; + } + + @Override + public SearchHits getHits() { + return searchHits; + } + + @Override + protected XContentBuilder doXContentBody(XContentBuilder builder, Params params) throws IOException { + return searchHits.toXContent(builder, params); + } + + private static ObjectParser PARSER = + new ObjectParser<>(ParsedTopHits.class.getSimpleName(), true, ParsedTopHits::new); + static { + declareAggregationFields(PARSER); + PARSER.declareObject((topHit, searchHits) -> topHit.searchHits = searchHits, (parser, context) -> SearchHits.fromXContent(parser), + new ParseField(SearchHits.Fields.HITS)); + } + + public static ParsedTopHits fromXContent(XContentParser parser, String name) throws IOException { + ParsedTopHits aggregation = PARSER.parse(parser, null); + aggregation.setName(name); + return aggregation; + } +} diff --git a/core/src/test/java/org/elasticsearch/search/aggregations/AggregationsTests.java b/core/src/test/java/org/elasticsearch/search/aggregations/AggregationsTests.java index 7a2ae447336..2a1df90a956 100644 --- a/core/src/test/java/org/elasticsearch/search/aggregations/AggregationsTests.java +++ b/core/src/test/java/org/elasticsearch/search/aggregations/AggregationsTests.java @@ -61,6 +61,7 @@ import org.elasticsearch.search.aggregations.metrics.percentiles.tdigest.Interna import org.elasticsearch.search.aggregations.metrics.percentiles.tdigest.InternalTDigestPercentilesTests; import org.elasticsearch.search.aggregations.metrics.scripted.InternalScriptedMetricTests; import org.elasticsearch.search.aggregations.metrics.sum.InternalSumTests; +import org.elasticsearch.search.aggregations.metrics.tophits.InternalTopHitsTests; import org.elasticsearch.search.aggregations.metrics.valuecount.InternalValueCountTests; import org.elasticsearch.search.aggregations.pipeline.InternalSimpleValueTests; import org.elasticsearch.search.aggregations.pipeline.bucketmetrics.InternalBucketMetricValueTests; @@ -134,6 +135,7 @@ public class AggregationsTests extends ESTestCase { aggsTests.add(new SignificantStringTermsTests()); aggsTests.add(new InternalScriptedMetricTests()); aggsTests.add(new InternalBinaryRangeTests()); + aggsTests.add(new InternalTopHitsTests()); return Collections.unmodifiableList(aggsTests); } diff --git a/core/src/test/java/org/elasticsearch/search/aggregations/metrics/tophits/InternalTopHitsTests.java b/core/src/test/java/org/elasticsearch/search/aggregations/metrics/tophits/InternalTopHitsTests.java index db68e8537df..af4e0bac3ec 100644 --- a/core/src/test/java/org/elasticsearch/search/aggregations/metrics/tophits/InternalTopHitsTests.java +++ b/core/src/test/java/org/elasticsearch/search/aggregations/metrics/tophits/InternalTopHitsTests.java @@ -33,9 +33,11 @@ import org.elasticsearch.common.text.Text; import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.SearchHitField; import org.elasticsearch.search.SearchHits; +import org.elasticsearch.search.aggregations.ParsedAggregation; import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator; import org.elasticsearch.test.InternalAggregationTestCase; +import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; @@ -54,11 +56,18 @@ public class InternalTopHitsTests extends InternalAggregationTestCase pipelineAggregators, Map metaData) { @@ -103,6 +112,35 @@ public class InternalTopHitsTests extends InternalAggregationTestCase expectedHits = Arrays.asList(expectedSearchHits.getHits()); + List actualHits = Arrays.asList(actualSearchHits.getHits()); + + assertEquals(expectedHits.size(), actualHits.size()); + for (int i = 0; i < expectedHits.size(); i++) { + SearchHit expected = expectedHits.get(i); + SearchHit actual = actualHits.get(i); + + assertEquals(expected.getIndex(), actual.getIndex()); + assertEquals(expected.getType(), actual.getType()); + assertEquals(expected.getId(), actual.getId()); + assertEquals(expected.getVersion(), actual.getVersion()); + assertEquals(expected.getScore(), actual.getScore(), 0.0f); + assertEquals(expected.getFields(), actual.getFields()); + assertEquals(expected.getSourceAsMap(), actual.getSourceAsMap()); + } + } + private Object randomOfType(SortField.Type type) { switch (type) { case CUSTOM: diff --git a/test/framework/src/main/java/org/elasticsearch/test/InternalAggregationTestCase.java b/test/framework/src/main/java/org/elasticsearch/test/InternalAggregationTestCase.java index 835f7292a32..56b521fdf79 100644 --- a/test/framework/src/main/java/org/elasticsearch/test/InternalAggregationTestCase.java +++ b/test/framework/src/main/java/org/elasticsearch/test/InternalAggregationTestCase.java @@ -106,6 +106,8 @@ import org.elasticsearch.search.aggregations.metrics.stats.extended.ExtendedStat import org.elasticsearch.search.aggregations.metrics.stats.extended.ParsedExtendedStats; import org.elasticsearch.search.aggregations.metrics.sum.ParsedSum; import org.elasticsearch.search.aggregations.metrics.sum.SumAggregationBuilder; +import org.elasticsearch.search.aggregations.metrics.tophits.ParsedTopHits; +import org.elasticsearch.search.aggregations.metrics.tophits.TopHitsAggregationBuilder; import org.elasticsearch.search.aggregations.metrics.valuecount.ParsedValueCount; import org.elasticsearch.search.aggregations.metrics.valuecount.ValueCountAggregationBuilder; import org.elasticsearch.search.aggregations.pipeline.InternalSimpleValue; @@ -187,6 +189,7 @@ public abstract class InternalAggregationTestCase map.put(SignificantStringTerms.NAME, (p, c) -> ParsedSignificantStringTerms.fromXContent(p, (String) c)); map.put(ScriptedMetricAggregationBuilder.NAME, (p, c) -> ParsedScriptedMetric.fromXContent(p, (String) c)); map.put(IpRangeAggregationBuilder.NAME, (p, c) -> ParsedBinaryRange.fromXContent(p, (String) c)); + map.put(TopHitsAggregationBuilder.NAME, (p, c) -> ParsedTopHits.fromXContent(p, (String) c)); namedXContents = map.entrySet().stream() .map(entry -> new NamedXContentRegistry.Entry(Aggregation.class, new ParseField(entry.getKey()), entry.getValue()))