16
16
import org .elasticsearch .search .aggregations .Aggregation ;
17
17
import org .elasticsearch .search .aggregations .AggregationBuilder ;
18
18
import org .elasticsearch .search .aggregations .PipelineAggregationBuilder ;
19
+ import org .elasticsearch .search .aggregations .bucket .SingleBucketAggregation ;
19
20
import org .elasticsearch .search .aggregations .bucket .composite .CompositeAggregation ;
20
21
import org .elasticsearch .search .aggregations .metrics .GeoBounds ;
21
22
import org .elasticsearch .search .aggregations .metrics .GeoCentroid ;
@@ -50,6 +51,7 @@ public final class AggregationResultUtils {
50
51
tempMap .put (GeoCentroid .class .getName (), new GeoCentroidAggExtractor ());
51
52
tempMap .put (GeoBounds .class .getName (), new GeoBoundsAggExtractor ());
52
53
tempMap .put (Percentiles .class .getName (), new PercentilesAggExtractor ());
54
+ tempMap .put (SingleBucketAggregation .class .getName (), new SingleBucketAggExtractor ());
53
55
TYPE_VALUE_EXTRACTOR_MAP = Collections .unmodifiableMap (tempMap );
54
56
}
55
57
@@ -94,9 +96,8 @@ public static Stream<Map<String, Object>> extractCompositeAggregationResults(
94
96
// present at all in the `bucket.getAggregations`. This could occur in the case of a `bucket_selector` agg, which
95
97
// does not calculate a value, but instead manipulates other results.
96
98
if (aggResult != null ) {
97
- final String fieldType = fieldTypeMap .get (aggName );
98
99
AggValueExtractor extractor = getExtractor (aggResult );
99
- updateDocument (document , aggName , extractor .value (aggResult , fieldType ));
100
+ updateDocument (document , aggName , extractor .value (aggResult , fieldTypeMap , "" ));
100
101
}
101
102
}
102
103
@@ -117,6 +118,8 @@ static AggValueExtractor getExtractor(Aggregation aggregation) {
117
118
return TYPE_VALUE_EXTRACTOR_MAP .get (GeoBounds .class .getName ());
118
119
} else if (aggregation instanceof Percentiles ) {
119
120
return TYPE_VALUE_EXTRACTOR_MAP .get (Percentiles .class .getName ());
121
+ } else if (aggregation instanceof SingleBucketAggregation ) {
122
+ return TYPE_VALUE_EXTRACTOR_MAP .get (SingleBucketAggregation .class .getName ());
120
123
} else {
121
124
// Execution should never reach this point!
122
125
// Creating transforms with unsupported aggregations shall not be possible
@@ -175,17 +178,19 @@ public static class AggregationExtractionException extends ElasticsearchExceptio
175
178
}
176
179
177
180
interface AggValueExtractor {
178
- Object value (Aggregation aggregation , String fieldType );
181
+ Object value (Aggregation aggregation , Map < String , String > fieldTypeMap , String lookupFieldPrefix );
179
182
}
180
183
181
184
static class SingleValueAggExtractor implements AggValueExtractor {
182
185
@ Override
183
- public Object value (Aggregation agg , String fieldType ) {
186
+ public Object value (Aggregation agg , Map < String , String > fieldTypeMap , String lookupFieldPrefix ) {
184
187
SingleValue aggregation = (SingleValue ) agg ;
185
188
// If the double is invalid, this indicates sparse data
186
189
if (Numbers .isValidDouble (aggregation .value ()) == false ) {
187
190
return null ;
188
191
}
192
+
193
+ String fieldType = fieldTypeMap .get (lookupFieldPrefix .isEmpty () ? agg .getName () : lookupFieldPrefix + "." + agg .getName ());
189
194
// If the type is numeric or if the formatted string is the same as simply making the value a string,
190
195
// gather the `value` type, otherwise utilize `getValueAsString` so we don't lose formatted outputs.
191
196
if (isNumericType (fieldType ) || aggregation .getValueAsString ().equals (String .valueOf (aggregation .value ()))) {
@@ -198,7 +203,7 @@ public Object value(Aggregation agg, String fieldType) {
198
203
199
204
static class PercentilesAggExtractor implements AggValueExtractor {
200
205
@ Override
201
- public Object value (Aggregation agg , String fieldType ) {
206
+ public Object value (Aggregation agg , Map < String , String > fieldTypeMap , String lookupFieldPrefix ) {
202
207
Percentiles aggregation = (Percentiles ) agg ;
203
208
204
209
HashMap <String , Double > percentiles = new HashMap <>();
@@ -211,17 +216,42 @@ public Object value(Aggregation agg, String fieldType) {
211
216
}
212
217
}
213
218
219
+ static class SingleBucketAggExtractor implements AggValueExtractor {
220
+ @ Override
221
+ public Object value (Aggregation agg , Map <String , String > fieldTypeMap , String lookupFieldPrefix ) {
222
+ SingleBucketAggregation aggregation = (SingleBucketAggregation ) agg ;
223
+
224
+ if (aggregation .getAggregations ().iterator ().hasNext () == false ) {
225
+ return aggregation .getDocCount ();
226
+ }
227
+
228
+ HashMap <String , Object > nested = new HashMap <>();
229
+ for (Aggregation subAgg : aggregation .getAggregations ()) {
230
+ nested .put (
231
+ subAgg .getName (),
232
+ getExtractor (subAgg ).value (
233
+ subAgg ,
234
+ fieldTypeMap ,
235
+ lookupFieldPrefix .isEmpty () ? agg .getName () : lookupFieldPrefix + "." + agg .getName ()
236
+ )
237
+ );
238
+ }
239
+
240
+ return nested ;
241
+ }
242
+ }
243
+
214
244
static class ScriptedMetricAggExtractor implements AggValueExtractor {
215
245
@ Override
216
- public Object value (Aggregation agg , String fieldType ) {
246
+ public Object value (Aggregation agg , Map < String , String > fieldTypeMap , String lookupFieldPrefix ) {
217
247
ScriptedMetric aggregation = (ScriptedMetric ) agg ;
218
248
return aggregation .aggregation ();
219
249
}
220
250
}
221
251
222
252
static class GeoCentroidAggExtractor implements AggValueExtractor {
223
253
@ Override
224
- public Object value (Aggregation agg , String fieldType ) {
254
+ public Object value (Aggregation agg , Map < String , String > fieldTypeMap , String lookupFieldPrefix ) {
225
255
GeoCentroid aggregation = (GeoCentroid ) agg ;
226
256
// if the account is `0` iff there is no contained centroid
227
257
return aggregation .count () > 0 ? aggregation .centroid ().toString () : null ;
@@ -230,7 +260,7 @@ public Object value(Aggregation agg, String fieldType) {
230
260
231
261
static class GeoBoundsAggExtractor implements AggValueExtractor {
232
262
@ Override
233
- public Object value (Aggregation agg , String fieldType ) {
263
+ public Object value (Aggregation agg , Map < String , String > fieldTypeMap , String lookupFieldPrefix ) {
234
264
GeoBounds aggregation = (GeoBounds ) agg ;
235
265
if (aggregation .bottomRight () == null || aggregation .topLeft () == null ) {
236
266
return null ;
0 commit comments