Skip to content

Commit 5ce6de2

Browse files
authored
Simplify SiblingPipelineAggregator (#53144) (#53341)
This removes the `instanceof`s from `SiblingPipelineAggregator` by adding a `rewriteBuckets` method to `InternalAggregation` that can be called to, well, rewrite the buckets. The default implementation of `rewriteBuckets` throws the same exception that was thrown when you attempted to run a `SiblingPipelineAggregator` on an aggregation without buckets. It is overridden by `InternalSingleBucketAggregation` and `InternalMultiBucketAggregation` to correctly rewrite their buckets.
1 parent 89c0e1f commit 5ce6de2

File tree

6 files changed

+67
-40
lines changed

6 files changed

+67
-40
lines changed

server/src/main/java/org/elasticsearch/search/aggregations/InternalAggregation.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import java.util.List;
3535
import java.util.Map;
3636
import java.util.Objects;
37+
import java.util.function.Function;
3738
import java.util.function.IntConsumer;
3839

3940
/**
@@ -127,6 +128,29 @@ public String getName() {
127128
return name;
128129
}
129130

131+
/**
132+
* Rewrite the sub-aggregations in the buckets in this aggregation.
133+
* Returns a copy of this {@linkplain InternalAggregation} with the
134+
* rewritten buckets, or, if there aren't any modifications to
135+
* the buckets then this method will return this aggregation. Either
136+
* way, it doesn't modify this aggregation.
137+
* <p>
138+
* Implementers of this should call the {@code rewriter} once per bucket
139+
* with its {@linkplain InternalAggregations}. The {@code rewriter}
140+
* should return {@code null} if it doen't have any rewriting to do or
141+
* it should return a new {@linkplain InternalAggregations} to make
142+
* changs.
143+
* <p>
144+
* The default implementation throws an exception because most
145+
* aggregations don't <strong>have</strong> buckets in them. It
146+
* should be overridden by aggregations that contain buckets. Implementers
147+
* should respect the description above.
148+
*/
149+
public InternalAggregation copyWithRewritenBuckets(Function<InternalAggregations, InternalAggregations> rewriter) {
150+
throw new IllegalStateException(
151+
"Aggregation [" + getName() + "] must be a bucket aggregation but was [" + getWriteableName() + "]");
152+
}
153+
130154
/**
131155
* Creates the output from all pipeline aggs that this aggregation is associated with. Should only
132156
* be called after all aggregations have been fully reduced

server/src/main/java/org/elasticsearch/search/aggregations/InternalAggregations.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,15 @@ public void writeTo(StreamOutput out) throws IOException {
9292
}
9393
}
9494

95+
/**
96+
* Make a mutable copy of the aggregation results.
97+
* <p>
98+
* IMPORTANT: The copy doesn't include any pipeline aggregations, if there are any.
99+
*/
100+
public List<InternalAggregation> copyResults() {
101+
return new ArrayList<>(getInternalAggregations());
102+
}
103+
95104
/**
96105
* Returns the top-level pipeline aggregators.
97106
* Note that top-level pipeline aggregators become normal aggregation once the final reduction has been performed, after which they

server/src/main/java/org/elasticsearch/search/aggregations/InternalMultiBucketAggregation.java

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import java.util.ArrayList;
3030
import java.util.List;
3131
import java.util.Map;
32+
import java.util.function.Function;
3233

3334
public abstract class InternalMultiBucketAggregation<A extends InternalMultiBucketAggregation,
3435
B extends InternalMultiBucketAggregation.InternalBucket>
@@ -154,6 +155,23 @@ public final InternalAggregation reducePipelines(InternalAggregation reducedAggs
154155
return super.reducePipelines(create(materializedBuckets), reduceContext);
155156
}
156157

158+
@Override
159+
public InternalAggregation copyWithRewritenBuckets(Function<InternalAggregations, InternalAggregations> rewriter) {
160+
boolean modified = false;
161+
List<B> newBuckets = new ArrayList<>();
162+
for (B bucket : getBuckets()) {
163+
InternalAggregations rewritten = rewriter.apply((InternalAggregations) bucket.getAggregations());
164+
if (rewritten == null) {
165+
newBuckets.add(bucket);
166+
continue;
167+
}
168+
modified = true;
169+
B newBucket = createBucket(rewritten, bucket);
170+
newBuckets.add(newBucket);
171+
}
172+
return modified ? create(newBuckets) : this;
173+
}
174+
157175
private List<B> reducePipelineBuckets(ReduceContext reduceContext) {
158176
List<B> reducedBuckets = new ArrayList<>();
159177
for (B bucket : getBuckets()) {
@@ -192,6 +210,5 @@ public Object getProperty(String containingAggName, List<String> path) {
192210
}
193211
return aggregation.getProperty(path.subList(1, path.size()));
194212
}
195-
196213
}
197214
}

server/src/main/java/org/elasticsearch/search/aggregations/bucket/InternalSingleBucketAggregation.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import java.util.List;
3434
import java.util.Map;
3535
import java.util.Objects;
36+
import java.util.function.Function;
3637

3738
/**
3839
* A base class for all the single bucket aggregations.
@@ -169,6 +170,15 @@ public final double sortValue(AggregationPath.PathElement head, Iterator<Aggrega
169170
return aggregations.sortValue(head, tail);
170171
}
171172

173+
@Override
174+
public InternalAggregation copyWithRewritenBuckets(Function<InternalAggregations, InternalAggregations> rewriter) {
175+
InternalAggregations rewritten = rewriter.apply(aggregations);
176+
if (rewritten == null) {
177+
return this;
178+
}
179+
return create(rewritten);
180+
}
181+
172182
@Override
173183
public boolean equals(Object obj) {
174184
if (this == obj) return true;

server/src/main/java/org/elasticsearch/search/aggregations/bucket/adjacency/InternalAdjacencyMatrix.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
import org.elasticsearch.common.io.stream.StreamInput;
2323
import org.elasticsearch.common.io.stream.StreamOutput;
2424
import org.elasticsearch.common.xcontent.XContentBuilder;
25-
import org.elasticsearch.search.aggregations.Aggregations;
2625
import org.elasticsearch.search.aggregations.InternalAggregation;
2726
import org.elasticsearch.search.aggregations.InternalAggregations;
2827
import org.elasticsearch.search.aggregations.InternalMultiBucketAggregation;
@@ -84,7 +83,7 @@ public long getDocCount() {
8483
}
8584

8685
@Override
87-
public Aggregations getAggregations() {
86+
public InternalAggregations getAggregations() {
8887
return aggregations;
8988
}
9089

server/src/main/java/org/elasticsearch/search/aggregations/pipeline/SiblingPipelineAggregator.java

Lines changed: 5 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,10 @@
2424
import org.elasticsearch.search.aggregations.InternalAggregation;
2525
import org.elasticsearch.search.aggregations.InternalAggregation.ReduceContext;
2626
import org.elasticsearch.search.aggregations.InternalAggregations;
27-
import org.elasticsearch.search.aggregations.InternalMultiBucketAggregation;
28-
import org.elasticsearch.search.aggregations.bucket.InternalSingleBucketAggregation;
29-
import org.elasticsearch.search.aggregations.bucket.MultiBucketsAggregation.Bucket;
3027

3128
import java.io.IOException;
32-
import java.util.ArrayList;
3329
import java.util.List;
3430
import java.util.Map;
35-
import java.util.stream.Collectors;
36-
import java.util.stream.StreamSupport;
3731

3832
public abstract class SiblingPipelineAggregator extends PipelineAggregator {
3933
protected SiblingPipelineAggregator(String name, String[] bucketsPaths, Map<String, Object> metaData) {
@@ -47,39 +41,13 @@ protected SiblingPipelineAggregator(String name, String[] bucketsPaths, Map<Stri
4741
super(in);
4842
}
4943

50-
@SuppressWarnings("unchecked")
5144
@Override
5245
public InternalAggregation reduce(InternalAggregation aggregation, ReduceContext reduceContext) {
53-
if (aggregation instanceof InternalMultiBucketAggregation) {
54-
@SuppressWarnings("rawtypes")
55-
InternalMultiBucketAggregation multiBucketsAgg = (InternalMultiBucketAggregation) aggregation;
56-
List<? extends Bucket> buckets = multiBucketsAgg.getBuckets();
57-
List<Bucket> newBuckets = new ArrayList<>();
58-
for (Bucket bucket1 : buckets) {
59-
InternalMultiBucketAggregation.InternalBucket bucket = (InternalMultiBucketAggregation.InternalBucket) bucket1;
60-
InternalAggregation aggToAdd = doReduce(bucket.getAggregations(), reduceContext);
61-
List<InternalAggregation> aggs = StreamSupport.stream(bucket.getAggregations().spliterator(), false)
62-
.map((p) -> (InternalAggregation) p)
63-
.collect(Collectors.toList());
64-
aggs.add(aggToAdd);
65-
InternalMultiBucketAggregation.InternalBucket newBucket = multiBucketsAgg.createBucket(new InternalAggregations(aggs),
66-
bucket);
67-
newBuckets.add(newBucket);
68-
}
69-
70-
return multiBucketsAgg.create(newBuckets);
71-
} else if (aggregation instanceof InternalSingleBucketAggregation) {
72-
InternalSingleBucketAggregation singleBucketAgg = (InternalSingleBucketAggregation) aggregation;
73-
InternalAggregation aggToAdd = doReduce(singleBucketAgg.getAggregations(), reduceContext);
74-
List<InternalAggregation> aggs = StreamSupport.stream(singleBucketAgg.getAggregations().spliterator(), false)
75-
.map((p) -> (InternalAggregation) p)
76-
.collect(Collectors.toList());
77-
aggs.add(aggToAdd);
78-
return singleBucketAgg.create(new InternalAggregations(aggs));
79-
} else {
80-
throw new IllegalStateException("Aggregation [" + aggregation.getName() + "] must be a bucket aggregation ["
81-
+ aggregation.getWriteableName() + "]");
82-
}
46+
return aggregation.copyWithRewritenBuckets(aggregations -> {
47+
List<InternalAggregation> aggs = aggregations.copyResults();
48+
aggs.add(doReduce(aggregations, reduceContext));
49+
return new InternalAggregations(aggs);
50+
});
8351
}
8452

8553
public abstract InternalAggregation doReduce(Aggregations aggregations, ReduceContext context);

0 commit comments

Comments
 (0)