@@ -72,9 +72,8 @@ public class HistogramAggregationBuilder extends ValuesSourceAggregationBuilder<
7272
7373 PARSER .declareLong (HistogramAggregationBuilder ::minDocCount , Histogram .MIN_DOC_COUNT_FIELD );
7474
75- PARSER .declareField ((histogram , extendedBounds ) -> {
76- histogram .extendedBounds (extendedBounds [0 ], extendedBounds [1 ]);
77- }, parser -> EXTENDED_BOUNDS_PARSER .apply (parser , null ), Histogram .EXTENDED_BOUNDS_FIELD , ObjectParser .ValueType .OBJECT );
75+ PARSER .declareField (HistogramAggregationBuilder ::extendedBounds , parser -> DoubleBounds .PARSER .apply (parser , null ),
76+ Histogram .EXTENDED_BOUNDS_FIELD , ObjectParser .ValueType .OBJECT );
7877
7978 PARSER .declareField (HistogramAggregationBuilder ::hardBounds , parser -> DoubleBounds .PARSER .apply (parser , null ),
8079 Histogram .HARD_BOUNDS_FIELD , ObjectParser .ValueType .OBJECT );
@@ -89,9 +88,7 @@ public static void registerAggregators(ValuesSourceRegistry.Builder builder) {
8988
9089 private double interval ;
9190 private double offset = 0 ;
92- //TODO: Replace with DoubleBounds
93- private double minBound = Double .POSITIVE_INFINITY ;
94- private double maxBound = Double .NEGATIVE_INFINITY ;
91+ private DoubleBounds extendedBounds ;
9592 private DoubleBounds hardBounds ;
9693 private BucketOrder order = BucketOrder .key (true );
9794 private boolean keyed = false ;
@@ -113,8 +110,7 @@ protected HistogramAggregationBuilder(HistogramAggregationBuilder clone,
113110 super (clone , factoriesBuilder , metadata );
114111 this .interval = clone .interval ;
115112 this .offset = clone .offset ;
116- this .minBound = clone .minBound ;
117- this .maxBound = clone .maxBound ;
113+ this .extendedBounds = clone .extendedBounds ;
118114 this .hardBounds = clone .hardBounds ;
119115 this .order = clone .order ;
120116 this .keyed = clone .keyed ;
@@ -134,8 +130,17 @@ public HistogramAggregationBuilder(StreamInput in) throws IOException {
134130 minDocCount = in .readVLong ();
135131 interval = in .readDouble ();
136132 offset = in .readDouble ();
137- minBound = in .readDouble ();
138- maxBound = in .readDouble ();
133+ if (in .getVersion ().onOrAfter (Version .V_8_0_0 )) {
134+ extendedBounds = in .readOptionalWriteable (DoubleBounds ::new );
135+ } else {
136+ double minBound = in .readDouble ();
137+ double maxBound = in .readDouble ();
138+ if (minBound == Double .POSITIVE_INFINITY && maxBound == Double .NEGATIVE_INFINITY ) {
139+ extendedBounds = null ;
140+ } else {
141+ extendedBounds = new DoubleBounds (minBound , maxBound );
142+ }
143+ }
139144 if (in .getVersion ().onOrAfter (Version .V_7_10_0 )) {
140145 hardBounds = in .readOptionalWriteable (DoubleBounds ::new );
141146 }
@@ -148,8 +153,17 @@ protected void innerWriteTo(StreamOutput out) throws IOException {
148153 out .writeVLong (minDocCount );
149154 out .writeDouble (interval );
150155 out .writeDouble (offset );
151- out .writeDouble (minBound );
152- out .writeDouble (maxBound );
156+ if (out .getVersion ().onOrAfter (Version .V_8_0_0 )) {
157+ out .writeOptionalWriteable (extendedBounds );
158+ } else {
159+ if (extendedBounds != null ) {
160+ out .writeDouble (extendedBounds .getMin ());
161+ out .writeDouble (extendedBounds .getMax ());
162+ } else {
163+ out .writeDouble (Double .POSITIVE_INFINITY );
164+ out .writeDouble (Double .NEGATIVE_INFINITY );
165+ }
166+ }
153167 if (out .getVersion ().onOrAfter (Version .V_7_10_0 )) {
154168 out .writeOptionalWriteable (hardBounds );
155169 }
@@ -182,12 +196,16 @@ public HistogramAggregationBuilder offset(double offset) {
182196
183197 /** Get the current minimum bound that is set on this builder. */
184198 public double minBound () {
185- return minBound ;
199+ return extendedBounds . getMin () ;
186200 }
187201
188202 /** Get the current maximum bound that is set on this builder. */
189203 public double maxBound () {
190- return maxBound ;
204+ return extendedBounds .getMax ();
205+ }
206+
207+ protected DoubleBounds extendedBounds () {
208+ return extendedBounds ;
191209 }
192210
193211 /**
@@ -200,17 +218,23 @@ public double maxBound() {
200218 * are not finite.
201219 */
202220 public HistogramAggregationBuilder extendedBounds (double minBound , double maxBound ) {
203- if (Double .isFinite (minBound ) == false ) {
204- throw new IllegalArgumentException ("minBound must be finite, got: " + minBound );
205- }
206- if (Double .isFinite (maxBound ) == false ) {
207- throw new IllegalArgumentException ("maxBound must be finite, got: " + maxBound );
208- }
209- if (maxBound < minBound ) {
210- throw new IllegalArgumentException ("maxBound [" + maxBound + "] must be greater than minBound [" + minBound + "]" );
221+ return extendedBounds (new DoubleBounds (minBound , maxBound ));
222+ }
223+
224+ /**
225+ * Set extended bounds on this builder: buckets between {@code minBound} and
226+ * {@code maxBound} will be created even if no documents fell into these
227+ * buckets.
228+ *
229+ * @throws IllegalArgumentException
230+ * if maxBound is less that minBound, or if either of the bounds
231+ * are not finite.
232+ */
233+ public HistogramAggregationBuilder extendedBounds (DoubleBounds extendedBounds ) {
234+ if (extendedBounds == null ) {
235+ throw new IllegalArgumentException ("[extended_bounds] must not be null: [" + name + "]" );
211236 }
212- this .minBound = minBound ;
213- this .maxBound = maxBound ;
237+ this .extendedBounds = extendedBounds ;
214238 return this ;
215239 }
216240
@@ -307,14 +331,15 @@ protected XContentBuilder doXContentBody(XContentBuilder builder, Params params)
307331
308332 builder .field (Histogram .MIN_DOC_COUNT_FIELD .getPreferredName (), minDocCount );
309333
310- if (Double . isFinite ( minBound ) || Double . isFinite ( maxBound ) ) {
334+ if (extendedBounds != null ) {
311335 builder .startObject (Histogram .EXTENDED_BOUNDS_FIELD .getPreferredName ());
312- if (Double .isFinite (minBound )) {
313- builder .field ("min" , minBound );
314- }
315- if (Double .isFinite (maxBound )) {
316- builder .field ("max" , maxBound );
317- }
336+ extendedBounds .toXContent (builder , params );
337+ builder .endObject ();
338+ }
339+
340+ if (hardBounds != null ) {
341+ builder .startObject (Histogram .HARD_BOUNDS_FIELD .getPreferredName ());
342+ hardBounds .toXContent (builder , params );
318343 builder .endObject ();
319344 }
320345
@@ -332,23 +357,23 @@ protected ValuesSourceAggregatorFactory innerBuild(QueryShardContext queryShardC
332357 AggregatorFactory parent ,
333358 AggregatorFactories .Builder subFactoriesBuilder ) throws IOException {
334359
335- if (hardBounds != null ) {
336- if (hardBounds .getMax () != null && hardBounds .getMax () < maxBound ) {
360+ if (hardBounds != null && extendedBounds != null ) {
361+ if (hardBounds .getMax () != null && extendedBounds . getMax () != null && hardBounds .getMax () < extendedBounds . getMax () ) {
337362 throw new IllegalArgumentException ("Extended bounds have to be inside hard bounds, hard bounds: [" +
338- hardBounds + "], extended bounds: [" + minBound + "--" + maxBound + "]" );
363+ hardBounds + "], extended bounds: [" + extendedBounds . getMin () + "--" + extendedBounds . getMax () + "]" );
339364 }
340- if (hardBounds .getMin () != null && hardBounds .getMin () > minBound ) {
365+ if (hardBounds .getMin () != null && extendedBounds . getMin () != null && hardBounds .getMin () > extendedBounds . getMin () ) {
341366 throw new IllegalArgumentException ("Extended bounds have to be inside hard bounds, hard bounds: [" +
342- hardBounds + "], extended bounds: [" + minBound + "--" + maxBound + "]" );
367+ hardBounds + "], extended bounds: [" + extendedBounds . getMin () + "--" + extendedBounds . getMax () + "]" );
343368 }
344369 }
345- return new HistogramAggregatorFactory (name , config , interval , offset , order , keyed , minDocCount , minBound , maxBound ,
370+ return new HistogramAggregatorFactory (name , config , interval , offset , order , keyed , minDocCount , extendedBounds ,
346371 hardBounds , queryShardContext , parent , subFactoriesBuilder , metadata );
347372 }
348373
349374 @ Override
350375 public int hashCode () {
351- return Objects .hash (super .hashCode (), order , keyed , minDocCount , interval , offset , minBound , maxBound , hardBounds );
376+ return Objects .hash (super .hashCode (), order , keyed , minDocCount , interval , offset , extendedBounds , hardBounds );
352377 }
353378
354379 @ Override
@@ -362,8 +387,7 @@ public boolean equals(Object obj) {
362387 && Objects .equals (minDocCount , other .minDocCount )
363388 && Objects .equals (interval , other .interval )
364389 && Objects .equals (offset , other .offset )
365- && Objects .equals (minBound , other .minBound )
366- && Objects .equals (maxBound , other .maxBound )
390+ && Objects .equals (extendedBounds , other .extendedBounds )
367391 && Objects .equals (hardBounds , other .hardBounds );
368392 }
369393}
0 commit comments