Skip to content

Commit c1ba699

Browse files
authored
AbstractParsedPercentiles should use Percentile class (#24160)
Now the Percentile interface has been merged with the InternalPercentile class in core (#24154) the AbstractParsedPercentiles should use it. This commit also changes InternalPercentilesRanksTestCase so that it now tests the iterator obtained from parsed percentiles ranks aggregations. Adding this new test raised an issue in the iterators where key and value are "swapped" in internal implementations when building the iterators (see InternalTDigestPercentileRanks.Iter constructor that accepts the `keys` as the first parameter named `values`, each key being mapped to the `value` field of Percentile class). This is because percentiles ranks aggs inverts percentiles/values compared to the percentiles aggs. * Add assume in InternalAggregationTestCase * Update after Luca review
1 parent 67a9696 commit c1ba699

File tree

5 files changed

+85
-6
lines changed

5 files changed

+85
-6
lines changed

core/src/main/java/org/elasticsearch/search/aggregations/metrics/percentiles/AbstractParsedPercentiles.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ public boolean hasNext() {
8181
@Override
8282
public Percentile next() {
8383
Map.Entry<Double, Double> next = iterator.next();
84-
return new InternalPercentile(next.getKey(), next.getValue());
84+
return new Percentile(next.getKey(), next.getValue());
8585
}
8686
};
8787
}

core/src/main/java/org/elasticsearch/search/aggregations/metrics/percentiles/hdr/ParsedHDRPercentileRanks.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,10 @@
2323
import org.elasticsearch.common.xcontent.XContentParser;
2424
import org.elasticsearch.search.aggregations.metrics.percentiles.AbstractParsedPercentiles;
2525
import org.elasticsearch.search.aggregations.metrics.percentiles.ParsedPercentileRanks;
26+
import org.elasticsearch.search.aggregations.metrics.percentiles.Percentile;
2627

2728
import java.io.IOException;
29+
import java.util.Iterator;
2830

2931
public class ParsedHDRPercentileRanks extends ParsedPercentileRanks {
3032

@@ -33,6 +35,23 @@ protected String getType() {
3335
return InternalHDRPercentileRanks.NAME;
3436
}
3537

38+
@Override
39+
public Iterator<Percentile> iterator() {
40+
final Iterator<Percentile> iterator = super.iterator();
41+
return new Iterator<Percentile>() {
42+
@Override
43+
public boolean hasNext() {
44+
return iterator.hasNext();
45+
}
46+
47+
@Override
48+
public Percentile next() {
49+
Percentile percentile = iterator.next();
50+
return new Percentile(percentile.getValue(), percentile.getPercent());
51+
}
52+
};
53+
}
54+
3655
private static ObjectParser<ParsedHDRPercentileRanks, Void> PARSER =
3756
new ObjectParser<>(ParsedHDRPercentileRanks.class.getSimpleName(), true, ParsedHDRPercentileRanks::new);
3857
static {

core/src/main/java/org/elasticsearch/search/aggregations/metrics/percentiles/tdigest/ParsedTDigestPercentileRanks.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,10 @@
2323
import org.elasticsearch.common.xcontent.XContentParser;
2424
import org.elasticsearch.search.aggregations.metrics.percentiles.AbstractParsedPercentiles;
2525
import org.elasticsearch.search.aggregations.metrics.percentiles.ParsedPercentileRanks;
26+
import org.elasticsearch.search.aggregations.metrics.percentiles.Percentile;
2627

2728
import java.io.IOException;
29+
import java.util.Iterator;
2830

2931
public class ParsedTDigestPercentileRanks extends ParsedPercentileRanks {
3032

@@ -33,6 +35,23 @@ protected String getType() {
3335
return InternalTDigestPercentileRanks.NAME;
3436
}
3537

38+
@Override
39+
public Iterator<Percentile> iterator() {
40+
final Iterator<Percentile> iterator = super.iterator();
41+
return new Iterator<Percentile>() {
42+
@Override
43+
public boolean hasNext() {
44+
return iterator.hasNext();
45+
}
46+
47+
@Override
48+
public Percentile next() {
49+
Percentile percentile = iterator.next();
50+
return new Percentile(percentile.getValue(), percentile.getPercent());
51+
}
52+
};
53+
}
54+
3655
private static ObjectParser<ParsedTDigestPercentileRanks, Void> PARSER =
3756
new ObjectParser<>(ParsedTDigestPercentileRanks.class.getSimpleName(), true, ParsedTDigestPercentileRanks::new);
3857
static {

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

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@
5454
import static java.util.Collections.singletonMap;
5555
import static org.elasticsearch.common.xcontent.XContentHelper.toXContent;
5656
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertToXContentEquivalent;
57-
import static org.hamcrest.Matchers.containsString;
5857

5958
public abstract class InternalAggregationTestCase<T extends InternalAggregation> extends AbstractWireSerializingTestCase<T> {
6059

@@ -169,6 +168,10 @@ public final void testFromXContent() throws IOException {
169168
final NamedXContentRegistry xContentRegistry = xContentRegistry();
170169
final T aggregation = createTestInstance();
171170

171+
//norelease Remove this assumption when all aggregations can be parsed back.
172+
assumeTrue("This test does not support the aggregation type yet",
173+
getNamedXContents().stream().filter(entry -> entry.name.match(aggregation.getType())).count() > 0);
174+
172175
final ToXContent.Params params = new ToXContent.MapParams(singletonMap(RestSearchAction.TYPED_KEYS_PARAM, "true"));
173176
final boolean humanReadable = randomBoolean();
174177
final XContentType xContentType = randomFrom(XContentType.values());
@@ -199,10 +202,6 @@ public final void testFromXContent() throws IOException {
199202
final BytesReference parsedBytes = toXContent((ToXContent) parsedAggregation, xContentType, params, humanReadable);
200203
assertToXContentEquivalent(originalBytes, parsedBytes, xContentType);
201204
assertFromXContent(aggregation, (ParsedAggregation) parsedAggregation);
202-
203-
} catch (NamedXContentRegistry.UnknownNamedObjectException e) {
204-
//norelease Remove this catch block when all aggregations can be parsed back.
205-
assertThat(e.getMessage(), containsString("Unknown Aggregation"));
206205
}
207206
}
208207

core/src/test/java/org/elasticsearch/search/aggregations/metrics/percentiles/InternalPercentilesRanksTestCase.java

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,26 @@
1919

2020
package org.elasticsearch.search.aggregations.metrics.percentiles;
2121

22+
import org.elasticsearch.common.bytes.BytesReference;
23+
import org.elasticsearch.common.xcontent.ToXContent;
24+
import org.elasticsearch.common.xcontent.XContentParser;
25+
import org.elasticsearch.common.xcontent.XContentType;
26+
import org.elasticsearch.rest.action.search.RestSearchAction;
2227
import org.elasticsearch.search.DocValueFormat;
28+
import org.elasticsearch.search.aggregations.Aggregation;
2329
import org.elasticsearch.search.aggregations.InternalAggregation;
2430
import org.elasticsearch.search.aggregations.InternalAggregationTestCase;
2531
import org.elasticsearch.search.aggregations.ParsedAggregation;
2632
import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
2733

34+
import java.io.IOException;
35+
import java.util.Iterator;
2836
import java.util.List;
2937
import java.util.Map;
3038

39+
import static java.util.Collections.singletonMap;
40+
import static org.elasticsearch.common.xcontent.XContentHelper.toXContent;
41+
3142
public abstract class InternalPercentilesRanksTestCase<T extends InternalAggregation> extends InternalAggregationTestCase<T> {
3243

3344
@Override
@@ -64,5 +75,36 @@ protected final void assertFromXContent(T aggregation, ParsedAggregation parsedA
6475
assertTrue(parsedClass.isInstance(parsedAggregation));
6576
}
6677

78+
public void testPercentilesRanksIterators() throws IOException {
79+
final T aggregation = createTestInstance();
80+
81+
final ToXContent.Params params = new ToXContent.MapParams(singletonMap(RestSearchAction.TYPED_KEYS_PARAM, "true"));
82+
final XContentType xContentType = randomFrom(XContentType.values());
83+
final BytesReference originalBytes = toXContent(aggregation, xContentType, params, randomBoolean());
84+
85+
Aggregation parsedAggregation;
86+
try (XContentParser parser = xContentType.xContent().createParser(xContentRegistry(), originalBytes)) {
87+
assertEquals(XContentParser.Token.START_OBJECT, parser.nextToken());
88+
assertEquals(XContentParser.Token.FIELD_NAME, parser.nextToken());
89+
90+
String currentName = parser.currentName();
91+
int i = currentName.indexOf(InternalAggregation.TYPED_KEYS_DELIMITER);
92+
String aggType = currentName.substring(0, i);
93+
String aggName = currentName.substring(i + 1);
94+
95+
parsedAggregation = parser.namedObject(Aggregation.class, aggType, aggName);
96+
97+
assertEquals(XContentParser.Token.END_OBJECT, parser.currentToken());
98+
assertEquals(XContentParser.Token.END_OBJECT, parser.nextToken());
99+
assertNull(parser.nextToken());
100+
}
101+
102+
final Iterator<Percentile> it = ((PercentileRanks) aggregation).iterator();
103+
final Iterator<Percentile> parsedIt = ((PercentileRanks) parsedAggregation).iterator();
104+
while (it.hasNext()) {
105+
assertEquals(it.next(), parsedIt.next());
106+
}
107+
}
108+
67109
protected abstract Class<? extends ParsedPercentileRanks> parsedParsedPercentileRanksClass();
68110
}

0 commit comments

Comments
 (0)