Passed
Pull Request — master (#35)
by Teye
04:28
created

HasPostAggregations   A

Complexity

Total Complexity 33

Size/Duplication

Total Lines 579
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 33
eloc 134
c 2
b 0
f 0
dl 0
loc 579
ccs 111
cts 111
cp 1
rs 9.76

21 Methods

Rating   Name   Duplication   Size   Complexity  
A quantiles() 0 14 2
A quantile() 0 14 2
A histogram() 0 15 2
A cdf() 0 14 2
A divide() 0 10 1
A buildFields() 0 30 6
A rank() 0 14 2
A longGreatest() 0 9 1
A quotient() 0 10 1
A multiply() 0 10 1
A getPostAggregations() 0 3 1
A fieldAccess() 0 9 2
A doubleGreatest() 0 9 1
A hyperUniqueCardinality() 0 5 1
A add() 0 10 1
A longLeast() 0 9 1
A doubleLeast() 0 9 1
A constant() 0 5 1
A subtract() 0 11 1
A sketchSummary() 0 13 2
A postJavascript() 0 9 1
1
<?php
2
declare(strict_types=1);
3
4
namespace Level23\Druid\Concerns;
5
6
use Closure;
7
use InvalidArgumentException;
8
use Level23\Druid\Types\DataType;
9
use Level23\Druid\PostAggregations\CdfPostAggregator;
10
use Level23\Druid\PostAggregations\RankPostAggregator;
11
use Level23\Druid\PostAggregations\LeastPostAggregator;
12
use Level23\Druid\Collections\PostAggregationCollection;
13
use Level23\Druid\PostAggregations\ConstantPostAggregator;
14
use Level23\Druid\PostAggregations\GreatestPostAggregator;
15
use Level23\Druid\PostAggregations\QuantilePostAggregator;
16
use Level23\Druid\PostAggregations\PostAggregationsBuilder;
17
use Level23\Druid\PostAggregations\PostAggregatorInterface;
18
use Level23\Druid\PostAggregations\QuantilesPostAggregator;
19
use Level23\Druid\PostAggregations\HistogramPostAggregator;
20
use Level23\Druid\PostAggregations\ArithmeticPostAggregator;
21
use Level23\Druid\PostAggregations\JavaScriptPostAggregator;
22
use Level23\Druid\PostAggregations\FieldAccessPostAggregator;
23
use Level23\Druid\PostAggregations\SketchSummaryPostAggregator;
24
use Level23\Druid\PostAggregations\HyperUniqueCardinalityPostAggregator;
25
26
trait HasPostAggregations
27
{
28
    /**
29
     * @var array|\Level23\Druid\PostAggregations\PostAggregatorInterface[]
30
     */
31
    protected $postAggregations = [];
32
33
    /**
34
     * Build our input field for the post aggregation.
35
     * This array can contain:
36
     *  - A string, referring to a metric or dimension in the query
37
     *  - A Closure, which allows you to build another postAggretator
38
     *
39
     * @param array $fields
40
     *
41
     * @return PostAggregationCollection
42
     * @throws InvalidArgumentException
43
     */
44 26
    protected function buildFields(array $fields): PostAggregationCollection
45
    {
46 26
        $first = reset($fields);
47
48 26
        if (is_array($first)) {
49 16
            $fields = $first;
50
        }
51
52 26
        $collection = new PostAggregationCollection();
53
54 26
        foreach ($fields as $field) {
55 26
            if (is_string($field)) {
56 25
                $collection->add(new FieldAccessPostAggregator($field, $field));
57 10
            } elseif ($field instanceof PostAggregatorInterface) {
58 1
                $collection->add($field);
59 10
            } elseif ($field instanceof Closure) {
60 9
                $builder = new PostAggregationsBuilder();
61 9
                call_user_func($field, $builder);
62 9
                $postAggregations = $builder->getPostAggregations();
63
64 9
                $collection->add(...$postAggregations);
65
            } else {
66 1
                throw new InvalidArgumentException(
67
                    'Incorrect field type given in postAggregation fields. Only strings (which will become' .
68
                    'FieldAccess types), Objects of the type PostAggregatorInterface and Closure\'s are allowed!'
69
                );
70
            }
71
        }
72
73 25
        return $collection;
74
    }
75
76
    /**
77
     * Divide two or more fields with each other.
78
     *
79
     * @param string               $as                The name which will be used in the output
80
     * @param string|Closure|array ...$fieldOrClosure One or more fields which will be used. When a string is given,
81
     *                                                we assume that it refers to another field in the query. If you
82
     *                                                give a closure, it will receive an instance of the
83
     *                                                PostAggregationsBuilder. With this builder you can build other
84
     *                                                post-aggregations or use constants as input for this method.
85
     *
86
     * @return $this
87
     */
88 7
    public function divide(string $as, ...$fieldOrClosure)
89
    {
90 7
        $this->postAggregations[] = new ArithmeticPostAggregator(
91
            $as,
92
            '/',
93 7
            $this->buildFields($fieldOrClosure),
94
            true
95
        );
96
97 7
        return $this;
98
    }
99
100
    /**
101
     * This returns an approximation to the value that would be preceded by a given fraction of a hypothetical sorted
102
     * version of the input stream.
103
     *
104
     * To use this aggregator, make sure you include the extension in your druid server config file:
105
     *
106
     * druid.extensions.loadList=["druid-datasketches"]
107
     *
108
     * @param string         $as             The name which will be used in the output
109
     * @param string|Closure $fieldOrClosure Field which will be used that refers to a DoublesSketch  (fieldAccess or
110
     *                                       another post aggregator). When a string is given, we assume that it refers
111
     *                                       to another field in the query. If you give a closure, it will receive an
112
     *                                       instance of the PostAggregationsBuilder. With this builder you can build
113
     *                                       another post-aggregation or use constants as input for this method.
114
     * @param float          $fraction       Fractional position in the hypothetical sorted stream, number from 0 to 1
115
     *                                       inclusive
116
     *
117
     * @return $this
118
     */
119 1
    public function quantile(string $as, $fieldOrClosure, float $fraction): self
120
    {
121 1
        $fields = $this->buildFields([$fieldOrClosure]);
122 1
        if ($fields->count() != 1) {
123 1
            throw new InvalidArgumentException('You can only provide one post-aggregation, field access or constant as input field');
124
        }
125
126 1
        $this->postAggregations[] = new QuantilePostAggregator(
127 1
            $fields[0], /** @scrutinizer ignore-type */
0 ignored issues
show
Bug introduced by
It seems like $fields[0] can also be of type null; however, parameter $dimension of Level23\Druid\PostAggreg...gregator::__construct() does only seem to accept Level23\Druid\PostAggreg...PostAggregatorInterface, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

127
            /** @scrutinizer ignore-type */ $fields[0], /** @scrutinizer ignore-type */
Loading history...
128
            $as,
129
            $fraction
130
        );
131
132 1
        return $this;
133
    }
134
135
    /**
136
     * This returns an approximation to the value that would be preceded by a given fraction of a hypothetical sorted
137
     * version of the input stream. This returns an array of quantiles corresponding to a given array of fractions.
138
     *
139
     * To use this aggregator, make sure you include the extension in your druid server config file:
140
     *
141
     * druid.extensions.loadList=["druid-datasketches"]
142
     *
143
     * @param string         $as             The name which will be used in the output
144
     * @param string|Closure $fieldOrClosure Field which will be used that refers to a DoublesSketch  (fieldAccess or
145
     *                                       another post aggregator). When a string is given, we assume that it refers
146
     *                                       to another field in the query. If you give a closure, it will receive an
147
     *                                       instance of the PostAggregationsBuilder. With this builder you can build
148
     *                                       another post-aggregation or use constants as input for this method.
149
     * @param float[]        $fractions      Array of Fractional positions in the hypothetical sorted stream, number
150
     *                                       from 0 to 1 inclusive
151
     *
152
     * @return $this
153
     */
154 1
    public function quantiles(string $as, $fieldOrClosure, array $fractions): self
155
    {
156 1
        $fields = $this->buildFields([$fieldOrClosure]);
157 1
        if ($fields->count() != 1) {
158 1
            throw new InvalidArgumentException('You can only provide one post-aggregation, field access or constant as input field');
159
        }
160
161 1
        $this->postAggregations[] = new QuantilesPostAggregator(
162 1
            $fields[0], /** @scrutinizer ignore-type */
0 ignored issues
show
Bug introduced by
It seems like $fields[0] can also be of type null; however, parameter $dimension of Level23\Druid\PostAggreg...gregator::__construct() does only seem to accept Level23\Druid\PostAggreg...PostAggregatorInterface, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

162
            /** @scrutinizer ignore-type */ $fields[0], /** @scrutinizer ignore-type */
Loading history...
163
            $as,
164
            $fractions
165
        );
166
167 1
        return $this;
168
    }
169
170
    /**
171
     * This returns an approximation to the histogram given an array of split points that define the histogram bins or
172
     * a number of bins (not both). An array of m unique, monotonically increasing split points divide the real number
173
     * line into m+1 consecutive disjoint intervals. The definition of an interval is inclusive of the left split point
174
     * and exclusive of the right split point. If the number of bins is specified instead of split points, the interval
175
     * between the minimum and maximum values is divided into the given number of equally-spaced bins.
176
     *
177
     * To use this aggregator, make sure you include the extension in your druid server config file:
178
     *
179
     * druid.extensions.loadList=["druid-datasketches"]
180
     *
181
     * @param string                $as             The name which will be used in the output
182
     * @param string|Closure        $fieldOrClosure Field which will be used that refers to a DoublesSketch
183
     *                                              (fieldAccess or another post aggregator). When a string is given,
184
     *                                              we assume that it refers to another field in the query. If you give
185
     *                                              a closure, it will receive an instance of the
186
     *                                              PostAggregationsBuilder. With this builder you can build another
187
     *                                              post-aggregation or use constants as input for this method.
188
     * @param array<int|float>|null $splitPoints    Array of split points (optional)
189
     * @param int|null              $numBins        Number of bins (optional, defaults to 10)
190
     *
191
     * @return $this
192
     */
193 3
    public function histogram(string $as, $fieldOrClosure, ?array $splitPoints = null, ?int $numBins = null): self
194
    {
195 3
        $fields = $this->buildFields([$fieldOrClosure]);
196 3
        if ($fields->count() != 1) {
197 3
            throw new InvalidArgumentException('You can only provide one post-aggregation, field access or constant as input field');
198
        }
199
200 3
        $this->postAggregations[] = new HistogramPostAggregator(
201 3
            $fields[0], /** @scrutinizer ignore-type */
0 ignored issues
show
Bug introduced by
It seems like $fields[0] can also be of type null; however, parameter $dimension of Level23\Druid\PostAggreg...gregator::__construct() does only seem to accept Level23\Druid\PostAggreg...PostAggregatorInterface, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

201
            /** @scrutinizer ignore-type */ $fields[0], /** @scrutinizer ignore-type */
Loading history...
202
            $as,
203
            $splitPoints,
204
            $numBins
205
        );
206
207 3
        return $this;
208
    }
209
210
    /**
211
     * This returns an approximation to the rank of a given value that is the fraction of the distribution less than
212
     * that value.
213
     *
214
     * To use this aggregator, make sure you include the extension in your druid server config file:
215
     *
216
     * druid.extensions.loadList=["druid-datasketches"]
217
     *
218
     * @param string         $as             The name which will be used in the output
219
     * @param string|Closure $fieldOrClosure Field which will be used that refers to a DoublesSketch  (fieldAccess or
220
     *                                       another post aggregator). When a string is given, we assume that it refers
221
     *                                       to another field in the query. If you give a closure, it will receive an
222
     *                                       instance of the PostAggregationsBuilder. With this builder you can build
223
     *                                       another post-aggregation or use constants as input for this method.
224
     * @param float|int      $value          This returns an approximation to the rank of a given value that is the
225
     *                                       fraction of the distribution less than that value.
226
     *
227
     * @return $this
228
     */
229 1
    public function rank(string $as, $fieldOrClosure, $value): self
230
    {
231 1
        $fields = $this->buildFields([$fieldOrClosure]);
232 1
        if ($fields->count() != 1) {
233 1
            throw new InvalidArgumentException('You can only provide one post-aggregation, field access or constant as input field');
234
        }
235
236 1
        $this->postAggregations[] = new RankPostAggregator(
237 1
            $fields[0], /** @scrutinizer ignore-type */
0 ignored issues
show
Bug introduced by
It seems like $fields[0] can also be of type null; however, parameter $dimension of Level23\Druid\PostAggreg...gregator::__construct() does only seem to accept Level23\Druid\PostAggreg...PostAggregatorInterface, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

237
            /** @scrutinizer ignore-type */ $fields[0], /** @scrutinizer ignore-type */
Loading history...
238
            $as,
239
            $value
240
        );
241
242 1
        return $this;
243
    }
244
245
    /**
246
     * This returns an approximation to the Cumulative Distribution Function given an array of split points that define
247
     * the edges of the bins. An array of m unique, monotonically increasing split points divide the real number line
248
     * into m+1 consecutive disjoint intervals. The definition of an interval is inclusive of the left split point and
249
     * exclusive of the right split point. The resulting array of fractions can be viewed as ranks of each split point
250
     * with one additional rank that is always 1.
251
     *
252
     * To use this aggregator, make sure you include the extension in your druid server config file:
253
     *
254
     * druid.extensions.loadList=["druid-datasketches"]
255
     *
256
     * @param string         $as             The name which will be used in the output
257
     * @param string|Closure $fieldOrClosure Field which will be used that refers to a DoublesSketch  (fieldAccess or
258
     *                                       another post aggregator). When a string is given, we assume that it refers
259
     *                                       to another field in the query. If you give a closure, it will receive an
260
     *                                       instance of the PostAggregationsBuilder. With this builder you can build
261
     *                                       another post-aggregation or use constants as input for this method.
262
     * @param array          $splitPoints    Array of split points
263
     *
264
     * @return $this
265
     */
266 1
    public function cdf(string $as, $fieldOrClosure, array $splitPoints): self
267
    {
268 1
        $fields = $this->buildFields([$fieldOrClosure]);
269 1
        if ($fields->count() != 1) {
270 1
            throw new InvalidArgumentException('You can only provide one post-aggregation, field access or constant as input field');
271
        }
272
273 1
        $this->postAggregations[] = new CdfPostAggregator(
274 1
            $fields[0], /** @scrutinizer ignore-type */
0 ignored issues
show
Bug introduced by
It seems like $fields[0] can also be of type null; however, parameter $dimension of Level23\Druid\PostAggreg...gregator::__construct() does only seem to accept Level23\Druid\PostAggreg...PostAggregatorInterface, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

274
            /** @scrutinizer ignore-type */ $fields[0], /** @scrutinizer ignore-type */
Loading history...
275
            $as,
276
            $splitPoints
277
        );
278
279 1
        return $this;
280
    }
281
282
    /**
283
     * This returns a summary of the sketch that can be used for debugging. This is the result of calling toString()
284
     * method.
285
     *
286
     * To use this aggregator, make sure you include the extension in your druid server config file:
287
     *
288
     * druid.extensions.loadList=["druid-datasketches"]
289
     *
290
     * @param string         $as             The name which will be used in the output
291
     * @param string|Closure $fieldOrClosure Field which will be used that refers to a DoublesSketch  (fieldAccess or
292
     *                                       another post aggregator). When a string is given, we assume that it refers
293
     *                                       to another field in the query. If you give a closure, it will receive an
294
     *                                       instance of the PostAggregationsBuilder. With this builder you can build
295
     *                                       another post-aggregation or use constants as input for this method.
296
     *
297
     * @return $this
298
     */
299 1
    public function sketchSummary(string $as, $fieldOrClosure): self
300
    {
301 1
        $fields = $this->buildFields([$fieldOrClosure]);
302 1
        if ($fields->count() != 1) {
303 1
            throw new InvalidArgumentException('You can only provide one post-aggregation, field access or constant as input field');
304
        }
305
306 1
        $this->postAggregations[] = new SketchSummaryPostAggregator(
307 1
            $fields[0], /** @scrutinizer ignore-type */
0 ignored issues
show
Bug introduced by
It seems like $fields[0] can also be of type null; however, parameter $dimension of Level23\Druid\PostAggreg...gregator::__construct() does only seem to accept Level23\Druid\PostAggreg...PostAggregatorInterface, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

307
            /** @scrutinizer ignore-type */ $fields[0], /** @scrutinizer ignore-type */
Loading history...
308
            $as
309
        );
310
311 1
        return $this;
312
    }
313
314
    /**
315
     * Multiply two or more fields with each other.
316
     *
317
     * @param string               $as                The name which will be used in the output
318
     * @param string|Closure|array ...$fieldOrClosure One or more fields which will be used. When a string is given,
319
     *                                                we assume that it refers to another field in the query. If you
320
     *                                                give a closure, it will receive an instance of the
321
     *                                                PostAggregationsBuilder. With this builder you can build other
322
     *                                                post-aggregations or use constants as input for this method.
323
     *
324
     * @return $this
325
     */
326 1
    public function multiply(string $as, ...$fieldOrClosure)
327
    {
328 1
        $this->postAggregations[] = new ArithmeticPostAggregator(
329
            $as,
330
            '*',
331 1
            $this->buildFields($fieldOrClosure),
332
            true
333
        );
334
335 1
        return $this;
336
    }
337
338
    /**
339
     * Subtract two or more fields with each other.
340
     *
341
     * @param string               $as                The name which will be used in the output
342
     * @param string|Closure|array ...$fieldOrClosure One or more fields which will be used. When a string is given,
343
     *                                                we assume that it refers to another field in the query. If you
344
     *                                                give a closure, it will receive an instance of the
345
     *                                                PostAggregationsBuilder. With this builder you can build other
346
     *                                                post-aggregations or use constants as input for this method.
347
     *
348
     * @return $this
349
     */
350 1
    public function subtract(string $as, ...$fieldOrClosure)
351
    {
352
353 1
        $this->postAggregations[] = new ArithmeticPostAggregator(
354
            $as,
355
            '-',
356 1
            $this->buildFields($fieldOrClosure),
357
            true
358
        );
359
360 1
        return $this;
361
    }
362
363
    /**
364
     * Add two or more fields with each other.
365
     *
366
     * @param string               $as                The name which will be used in the output
367
     * @param string|Closure|array ...$fieldOrClosure One or more fields which will be used. When a string is given,
368
     *                                                we assume that it refers to another field in the query. If you
369
     *                                                give a closure, it will receive an instance of the
370
     *                                                PostAggregationsBuilder. With this builder you can build other
371
     *                                                post-aggregations or use constants as input for this method.
372
     *
373
     * @return $this
374
     */
375 1
    public function add(string $as, ...$fieldOrClosure)
376
    {
377 1
        $this->postAggregations[] = new ArithmeticPostAggregator(
378
            $as,
379
            '+',
380 1
            $this->buildFields($fieldOrClosure),
381
            true
382
        );
383
384 1
        return $this;
385
    }
386
387
    /**
388
     * Return the quotient of two or more fields.
389
     *
390
     * @param string               $as                The name which will be used in the output
391
     * @param string|Closure|array ...$fieldOrClosure One or more fields which will be used. When a string is given,
392
     *                                                we assume that it refers to another field in the query. If you
393
     *                                                give a closure, it will receive an instance of the
394
     *                                                PostAggregationsBuilder. With this builder you can build other
395
     *                                                post-aggregations or use constants as input for this method.
396
     *
397
     * @return $this
398
     */
399 1
    public function quotient(string $as, ...$fieldOrClosure)
400
    {
401 1
        $this->postAggregations[] = new ArithmeticPostAggregator(
402
            $as,
403
            'quotient',
404 1
            $this->buildFields($fieldOrClosure),
405
            true
406
        );
407
408 1
        return $this;
409
    }
410
411
    /**
412
     * Field accessor post-aggregators
413
     *
414
     * These post-aggregators return the value produced by the specified aggregator.
415
     *
416
     * $aggregatorOutputName refers to the output name of the aggregator given in the aggregations portion of the
417
     * query. For complex aggregators, like "cardinality" and "hyperUnique", the type of the post-aggregator determines
418
     * what the post-aggregator will return.
419
     * Set $finalizing to `false`  to return the raw aggregation object, or use `true`
420
     * to return a finalized value, such as an estimated cardinality.
421
     *
422
     * @param string $aggregatorOutputName This refers to the output name of the aggregator given in the aggregations
423
     *                                     portion of the query
424
     * @param string $as                   The output name as how we can access it
425
     * @param bool   $finalizing           Set this to true if you want to return a finalized value, such as an
426
     *                                     estimated cardinality.
427
     *
428
     * @return $this
429
     */
430 11
    public function fieldAccess(string $aggregatorOutputName, string $as = '', bool $finalizing = false)
431
    {
432 11
        $this->postAggregations[] = new FieldAccessPostAggregator(
433
            $aggregatorOutputName,
434 11
            ($as ?: $aggregatorOutputName),
435
            $finalizing
436
        );
437
438 11
        return $this;
439
    }
440
441
    /**
442
     * The constant post-aggregator always returns the specified value.
443
     *
444
     * @param int|float $numericValue This will be our static value
445
     * @param string    $as           The output name as how we can access it
446
     *
447
     * @return $this
448
     */
449 11
    public function constant($numericValue, string $as)
450
    {
451 11
        $this->postAggregations[] = new ConstantPostAggregator($as, $numericValue);
452
453 11
        return $this;
454
    }
455
456
    /**
457
     * Return the highest value of multiple columns in one row.
458
     *
459
     * @param string               $as                The name which will be used in the output
460
     * @param string|Closure|array ...$fieldOrClosure One or more fields which will be used. When a string is given,
461
     *                                                we assume that it refers to another field in the query. If you
462
     *                                                give a closure, it will receive an instance of the
463
     *                                                PostAggregationsBuilder. With this builder you can build other
464
     *                                                post-aggregations or use constants as input for this method.
465
     *
466
     * @return $this
467
     */
468 1
    public function longGreatest(string $as, ...$fieldOrClosure)
469
    {
470 1
        $this->postAggregations[] = new GreatestPostAggregator(
471
            $as,
472 1
            $this->buildFields($fieldOrClosure),
473
            DataType::LONG
474
        );
475
476 1
        return $this;
477
    }
478
479
    /**
480
     * Return the highest value of multiple columns in one row.
481
     *
482
     * @param string               $as                The name which will be used in the output
483
     * @param string|Closure|array ...$fieldOrClosure One or more fields which will be used. When a string is given,
484
     *                                                we assume that it refers to another field in the query. If you
485
     *                                                give a closure, it will receive an instance of the
486
     *                                                PostAggregationsBuilder. With this builder you can build other
487
     *                                                post-aggregations or use constants as input for this method.
488
     *
489
     * @return $this
490
     */
491 1
    public function doubleGreatest(string $as, ...$fieldOrClosure)
492
    {
493 1
        $this->postAggregations[] = new GreatestPostAggregator(
494
            $as,
495 1
            $this->buildFields($fieldOrClosure),
496
            DataType::DOUBLE
497
        );
498
499 1
        return $this;
500
    }
501
502
    /**
503
     * Return the lowest value of multiple columns in one row.
504
     *
505
     * @param string               $as                The name which will be used in the output
506
     * @param string|Closure|array ...$fieldOrClosure One or more fields which will be used. When a string is given,
507
     *                                                we assume that it refers to another field in the query. If you
508
     *                                                give a closure, it will receive an instance of the
509
     *                                                PostAggregationsBuilder. With this builder you can build other
510
     *                                                post-aggregations or use constants as input for this method.
511
     *
512
     * @return $this
513
     */
514 1
    public function longLeast(string $as, ...$fieldOrClosure)
515
    {
516 1
        $this->postAggregations[] = new LeastPostAggregator(
517
            $as,
518 1
            $this->buildFields($fieldOrClosure),
519
            DataType::LONG
520
        );
521
522 1
        return $this;
523
    }
524
525
    /**
526
     * Return the lowest value of multiple columns in one row.
527
     *
528
     * @param string               $as                The name which will be used in the output
529
     * @param string|Closure|array ...$fieldOrClosure One or more fields which will be used. When a string is given,
530
     *                                                we assume that it refers to another field in the query. If you
531
     *                                                give a closure, it will receive an instance of the
532
     *                                                PostAggregationsBuilder. With this builder you can build other
533
     *                                                post-aggregations or use constants as input for this method.
534
     *
535
     * @return $this
536
     */
537 1
    public function doubleLeast(string $as, ...$fieldOrClosure)
538
    {
539 1
        $this->postAggregations[] = new LeastPostAggregator(
540
            $as,
541 1
            $this->buildFields($fieldOrClosure),
542
            DataType::DOUBLE
543
        );
544
545 1
        return $this;
546
    }
547
548
    /**
549
     * This Post Aggregation function applies the provided JavaScript function to the given fields. Fields are passed
550
     * as arguments to the JavaScript function in the given order.
551
     *
552
     * NOTE: JavaScript-based functionality is disabled by default. Please refer to the Druid JavaScript programming
553
     * guide for guidelines about using Druid's JavaScript functionality, including instructions on how to enable it.
554
     *
555
     * @param string               $as                The output name
556
     * @param string               $function          The javascript function which should be applied.
557
     * @param string|Closure|array ...$fieldOrClosure One or more fields which will be used. When a string is given,
558
     *                                                we assume that it refers to another field in the query. If you
559
     *                                                give a closure, it will receive an instance of the
560
     *                                                PostAggregationsBuilder. With this builder you can build other
561
     *                                                post-aggregations or use constants as input for this method.
562
     *
563
     * @return $this
564
     * @see https://druid.apache.org/docs/latest/querying/post-aggregations.html#javascript-post-aggregator
565
     */
566 1
    public function postJavascript(string $as, string $function, ...$fieldOrClosure)
567
    {
568 1
        $this->postAggregations[] = new JavaScriptPostAggregator(
569
            $as,
570 1
            $this->buildFields($fieldOrClosure),
571
            $function
572
        );
573
574 1
        return $this;
575
    }
576
577
    /**
578
     * The hyperUniqueCardinality post aggregator is used to wrap a hyperUnique object such that it can be used in post
579
     * aggregations.
580
     *
581
     * This post-aggregator will inherit the rounding behavior of the aggregator it references. Note that this
582
     * inheritance is only effective if you directly reference an aggregator. Going through another post-aggregator,
583
     * for example, will cause the user-specified rounding behavior to get lost and default to "no rounding".
584
     *
585
     * @see https://druid.apache.org/docs/latest/querying/post-aggregations.html#hyperunique-cardinality-post-aggregator
586
     *
587
     * @param string      $hyperUniqueField The name field value of the hyperUnique aggregator
588
     * @param string|null $as               The output name
589
     *
590
     * @return $this
591
     */
592 1
    public function hyperUniqueCardinality(string $hyperUniqueField, string $as = null)
593
    {
594 1
        $this->postAggregations[] = new HyperUniqueCardinalityPostAggregator($hyperUniqueField, $as);
595
596 1
        return $this;
597
    }
598
599
    /**
600
     * @return array|\Level23\Druid\PostAggregations\PostAggregatorInterface[]
601
     */
602 10
    public function getPostAggregations(): array
603
    {
604 10
        return $this->postAggregations;
605
    }
606
}