6
6
7
7
package org .elasticsearch .xpack .dataframe .transforms .pivot ;
8
8
9
- import org .apache .logging .log4j .LogManager ;
10
- import org .apache .logging .log4j .Logger ;
11
9
import org .elasticsearch .ElasticsearchException ;
10
+ import org .elasticsearch .common .Numbers ;
12
11
import org .elasticsearch .search .aggregations .Aggregation ;
13
12
import org .elasticsearch .search .aggregations .AggregationBuilder ;
14
13
import org .elasticsearch .search .aggregations .PipelineAggregationBuilder ;
15
14
import org .elasticsearch .search .aggregations .bucket .composite .CompositeAggregation ;
16
15
import org .elasticsearch .search .aggregations .metrics .GeoCentroid ;
17
- import org .elasticsearch .search .aggregations .metrics .NumericMetricsAggregation ;
18
16
import org .elasticsearch .search .aggregations .metrics .NumericMetricsAggregation .SingleValue ;
19
17
import org .elasticsearch .search .aggregations .metrics .ScriptedMetric ;
20
18
import org .elasticsearch .xpack .core .dataframe .DataFrameField ;
23
21
import org .elasticsearch .xpack .dataframe .transforms .IDGenerator ;
24
22
25
23
import java .util .Collection ;
24
+ import java .util .Collections ;
26
25
import java .util .HashMap ;
27
26
import java .util .List ;
28
27
import java .util .Map ;
32
31
import static org .elasticsearch .xpack .dataframe .transforms .pivot .SchemaUtil .isNumericType ;
33
32
34
33
public final class AggregationResultUtils {
35
- private static final Logger logger = LogManager .getLogger (AggregationResultUtils .class );
34
+
35
+ private static final Map <String , AggValueExtractor > TYPE_VALUE_EXTRACTOR_MAP ;
36
+ static {
37
+ Map <String , AggValueExtractor > tempMap = new HashMap <>();
38
+ tempMap .put (SingleValue .class .getName (), new SingleValueAggExtractor ());
39
+ tempMap .put (ScriptedMetric .class .getName (), new ScriptedMetricAggExtractor ());
40
+ tempMap .put (GeoCentroid .class .getName (), new GeoCentroidAggExtractor ());
41
+ TYPE_VALUE_EXTRACTOR_MAP = Collections .unmodifiableMap (tempMap );
42
+ }
36
43
37
44
/**
38
45
* Extracts aggregation results from a composite aggregation and puts it into a map.
@@ -73,27 +80,8 @@ public static Stream<Map<String, Object>> extractCompositeAggregationResults(Com
73
80
// TODO: support other aggregation types
74
81
Aggregation aggResult = bucket .getAggregations ().get (aggName );
75
82
76
- if (aggResult instanceof NumericMetricsAggregation .SingleValue ) {
77
- NumericMetricsAggregation .SingleValue aggResultSingleValue = (SingleValue ) aggResult ;
78
- // If the type is numeric or if the formatted string is the same as simply making the value a string,
79
- // gather the `value` type, otherwise utilize `getValueAsString` so we don't lose formatted outputs.
80
- if (isNumericType (fieldType ) ||
81
- (aggResultSingleValue .getValueAsString ().equals (String .valueOf (aggResultSingleValue .value ())))) {
82
- updateDocument (document , aggName , aggResultSingleValue .value ());
83
- } else {
84
- updateDocument (document , aggName , aggResultSingleValue .getValueAsString ());
85
- }
86
- } else if (aggResult instanceof ScriptedMetric ) {
87
- updateDocument (document , aggName , ((ScriptedMetric ) aggResult ).aggregation ());
88
- } else if (aggResult instanceof GeoCentroid ) {
89
- updateDocument (document , aggName , ((GeoCentroid ) aggResult ).centroid ().toString ());
90
- } else {
91
- // Execution should never reach this point!
92
- // Creating transforms with unsupported aggregations shall not be possible
93
- throw new AggregationExtractionException ("unsupported aggregation [{}] with name [{}]" ,
94
- aggResult .getType (),
95
- aggResult .getName ());
96
- }
83
+ AggValueExtractor extractor = getExtractor (aggResult );
84
+ updateDocument (document , aggName , extractor .value (aggResult , fieldType ));
97
85
}
98
86
99
87
document .put (DataFrameField .DOCUMENT_ID_FIELD , idGen .getID ());
@@ -102,6 +90,23 @@ public static Stream<Map<String, Object>> extractCompositeAggregationResults(Com
102
90
});
103
91
}
104
92
93
+ static AggValueExtractor getExtractor (Aggregation aggregation ) {
94
+ if (aggregation instanceof SingleValue ) {
95
+ return TYPE_VALUE_EXTRACTOR_MAP .get (SingleValue .class .getName ());
96
+ } else if (aggregation instanceof ScriptedMetric ) {
97
+ return TYPE_VALUE_EXTRACTOR_MAP .get (ScriptedMetric .class .getName ());
98
+ } else if (aggregation instanceof GeoCentroid ) {
99
+ return TYPE_VALUE_EXTRACTOR_MAP .get (GeoCentroid .class .getName ());
100
+ } else {
101
+ // Execution should never reach this point!
102
+ // Creating transforms with unsupported aggregations shall not be possible
103
+ throw new AggregationExtractionException ("unsupported aggregation [{}] with name [{}]" ,
104
+ aggregation .getType (),
105
+ aggregation .getName ());
106
+ }
107
+ }
108
+
109
+
105
110
@ SuppressWarnings ("unchecked" )
106
111
static void updateDocument (Map <String , Object > document , String fieldName , Object value ) {
107
112
String [] fieldTokens = fieldName .split ("\\ ." );
@@ -147,4 +152,44 @@ public static class AggregationExtractionException extends ElasticsearchExceptio
147
152
super (msg , args );
148
153
}
149
154
}
155
+
156
+ private interface AggValueExtractor {
157
+ Object value (Aggregation aggregation , String fieldType );
158
+ }
159
+
160
+ private static class SingleValueAggExtractor implements AggValueExtractor {
161
+ @ Override
162
+ public Object value (Aggregation agg , String fieldType ) {
163
+ SingleValue aggregation = (SingleValue )agg ;
164
+ // If the double is invalid, this indicates sparse data
165
+ if (Numbers .isValidDouble (aggregation .value ()) == false ) {
166
+ return null ;
167
+ }
168
+ // If the type is numeric or if the formatted string is the same as simply making the value a string,
169
+ // gather the `value` type, otherwise utilize `getValueAsString` so we don't lose formatted outputs.
170
+ if (isNumericType (fieldType ) ||
171
+ aggregation .getValueAsString ().equals (String .valueOf (aggregation .value ()))){
172
+ return aggregation .value ();
173
+ } else {
174
+ return aggregation .getValueAsString ();
175
+ }
176
+ }
177
+ }
178
+
179
+ private static class ScriptedMetricAggExtractor implements AggValueExtractor {
180
+ @ Override
181
+ public Object value (Aggregation agg , String fieldType ) {
182
+ ScriptedMetric aggregation = (ScriptedMetric )agg ;
183
+ return aggregation .aggregation ();
184
+ }
185
+ }
186
+
187
+ private static class GeoCentroidAggExtractor implements AggValueExtractor {
188
+ @ Override
189
+ public Object value (Aggregation agg , String fieldType ) {
190
+ GeoCentroid aggregation = (GeoCentroid )agg ;
191
+ // if the account is `0` iff there is no contained centroid
192
+ return aggregation .count () > 0 ? aggregation .centroid ().toString () : null ;
193
+ }
194
+ }
150
195
}
0 commit comments