22
22
import org .elasticsearch .common .ParseField ;
23
23
import org .elasticsearch .common .io .stream .StreamInput ;
24
24
import org .elasticsearch .common .io .stream .StreamOutput ;
25
+ import org .elasticsearch .common .xcontent .ConstructingObjectParser ;
26
+ import org .elasticsearch .common .xcontent .ContextParser ;
25
27
import org .elasticsearch .common .xcontent .ObjectParser ;
26
28
import org .elasticsearch .common .xcontent .XContentBuilder ;
27
29
import org .elasticsearch .common .xcontent .XContentParser ;
42
44
43
45
import java .io .IOException ;
44
46
import java .util .Arrays ;
47
+ import java .util .List ;
45
48
import java .util .Objects ;
49
+ import java .util .function .BiConsumer ;
50
+
51
+ import static org .elasticsearch .common .xcontent .ConstructingObjectParser .constructorArg ;
46
52
47
53
public class PercentileRanksAggregationBuilder extends LeafOnly <ValuesSource .Numeric , PercentileRanksAggregationBuilder > {
48
54
public static final String NAME = PercentileRanks .TYPE_NAME ;
@@ -53,7 +59,7 @@ private static class TDigestOptions {
53
59
Double compression ;
54
60
}
55
61
56
- private static final ObjectParser <TDigestOptions , Void > TDIGEST_OPTIONS_PARSER =
62
+ private static final ObjectParser <TDigestOptions , String > TDIGEST_OPTIONS_PARSER =
57
63
new ObjectParser <>(PercentilesMethod .TDIGEST .getParseField ().getPreferredName (), TDigestOptions ::new );
58
64
static {
59
65
TDIGEST_OPTIONS_PARSER .declareDouble ((opts , compression ) -> opts .compression = compression , new ParseField ("compression" ));
@@ -63,22 +69,22 @@ private static class HDROptions {
63
69
Integer numberOfSigDigits ;
64
70
}
65
71
66
- private static final ObjectParser <HDROptions , Void > HDR_OPTIONS_PARSER =
72
+ private static final ObjectParser <HDROptions , String > HDR_OPTIONS_PARSER =
67
73
new ObjectParser <>(PercentilesMethod .HDR .getParseField ().getPreferredName (), HDROptions ::new );
68
74
static {
69
75
HDR_OPTIONS_PARSER .declareInt ((opts , numberOfSigDigits ) -> opts .numberOfSigDigits = numberOfSigDigits ,
70
76
new ParseField ("number_of_significant_value_digits" ));
71
77
}
72
78
73
- private static final ObjectParser <PercentileRanksAggregationBuilder , Void > PARSER ;
79
+ // The builder requires two parameters for the constructor: aggregation name and values array. The
80
+ // agg name is supplied externally via the Parser's context (as a String), while the values array
81
+ // is parsed from the request and supplied to the ConstructingObjectParser as a ctor argument
82
+ private static final ConstructingObjectParser <PercentileRanksAggregationBuilder , String > PARSER ;
74
83
static {
75
- PARSER = new ObjectParser <>(PercentileRanksAggregationBuilder .NAME );
84
+ PARSER = new ConstructingObjectParser <>(PercentileRanksAggregationBuilder .NAME , false ,
85
+ (a , context ) -> new PercentileRanksAggregationBuilder (context , (List ) a [0 ]));
76
86
ValuesSourceParserHelper .declareNumericFields (PARSER , true , false , false );
77
-
78
- PARSER .declareDoubleArray (
79
- (b , v ) -> b .values (v .stream ().mapToDouble (Double ::doubleValue ).toArray ()),
80
- VALUES_FIELD );
81
-
87
+ PARSER .declareDoubleArray (constructorArg (), VALUES_FIELD );
82
88
PARSER .declareBoolean (PercentileRanksAggregationBuilder ::keyed , PercentilesAggregationBuilder .KEYED_FIELD );
83
89
84
90
PARSER .declareField ((b , v ) -> {
@@ -97,7 +103,8 @@ private static class HDROptions {
97
103
}
98
104
99
105
public static AggregationBuilder parse (String aggregationName , XContentParser parser ) throws IOException {
100
- return PARSER .parse (parser , new PercentileRanksAggregationBuilder (aggregationName ), null );
106
+ // the aggregation name is supplied to the parser as a Context. See note at top of Parser for more details
107
+ return PARSER .parse (parser , aggregationName );
101
108
}
102
109
103
110
private double [] values ;
@@ -106,8 +113,21 @@ public static AggregationBuilder parse(String aggregationName, XContentParser pa
106
113
private double compression = 100.0 ;
107
114
private boolean keyed = true ;
108
115
109
- public PercentileRanksAggregationBuilder (String name ) {
116
+ private PercentileRanksAggregationBuilder (String name , List <Double > values ) {
117
+ this (name , values .stream ().mapToDouble (Double ::doubleValue ).toArray ());
118
+ }
119
+
120
+ public PercentileRanksAggregationBuilder (String name , double [] values ) {
110
121
super (name , ValuesSourceType .NUMERIC , ValueType .NUMERIC );
122
+ if (values == null ) {
123
+ throw new IllegalArgumentException ("[values] must not be null: [" + name + "]" );
124
+ }
125
+ if (values .length == 0 ) {
126
+ throw new IllegalArgumentException ("[values] must not be an empty array: [" + name + "]" );
127
+ }
128
+ double [] sortedValues = Arrays .copyOf (values , values .length );
129
+ Arrays .sort (sortedValues );
130
+ this .values = sortedValues ;
111
131
}
112
132
113
133
/**
@@ -131,19 +151,6 @@ protected void innerWriteTo(StreamOutput out) throws IOException {
131
151
method .writeTo (out );
132
152
}
133
153
134
- /**
135
- * Set the values to compute percentiles from.
136
- */
137
- public PercentileRanksAggregationBuilder values (double ... values ) {
138
- if (values == null ) {
139
- throw new IllegalArgumentException ("[values] must not be null: [" + name + "]" );
140
- }
141
- double [] sortedValues = Arrays .copyOf (values , values .length );
142
- Arrays .sort (sortedValues );
143
- this .values = sortedValues ;
144
- return this ;
145
- }
146
-
147
154
/**
148
155
* Get the values to compute percentiles from.
149
156
*/
0 commit comments