From 62c8aeefdfb3ea10fe1ff3b633a1de7f8057c77e Mon Sep 17 00:00:00 2001 From: Romain Neutron Date: Mon, 23 Nov 2020 17:59:38 +0100 Subject: [PATCH] Add "keyed" behavior to some aggregations --- CHANGELOG.md | 5 +++++ src/Aggregation/GeoDistance.php | 2 ++ src/Aggregation/Histogram.php | 2 ++ src/Aggregation/IpRange.php | 2 ++ src/Aggregation/KeyedTrait.php | 17 +++++++++++++++++ src/Aggregation/Percentiles.php | 14 ++------------ src/Aggregation/PercentilesBucket.php | 10 ++-------- src/Aggregation/Range.php | 12 ++---------- tests/Aggregation/DateHistogramTest.php | 21 +++++++++++++++++++++ tests/Aggregation/DateRangeTest.php | 21 +++++++++++++++++++++ tests/Aggregation/GeoDistanceTest.php | 20 ++++++++++++++++++++ tests/Aggregation/HistogramTest.php | 23 +++++++++++++++++++++++ tests/Aggregation/IpRangeTest.php | 25 +++++++++++++++++++++++++ tests/Aggregation/RangeTest.php | 20 ++++++++++++++++++++ 14 files changed, 164 insertions(+), 30 deletions(-) create mode 100644 src/Aggregation/KeyedTrait.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 8be0a7d66f..1469c45388 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased](https://github.com/ruflin/Elastica/compare/7.0.0...master) ### Backward Compatibility Breaks * Allow the Terms query to accept arrays of strings, ints and floats [#1872](https://github.com/ruflin/Elastica/pull/1872) +* Added a default value to `Elastica\Aggregation\Range::setKeyed()` and `Elastica\Aggregation\PercentilesBucket::setKeyed()` [#1876](https://github.com/ruflin/Elastica/pull/1876) ### Added * Ability to specify the type of authentication manually by the `auth_type` parameter (in the client class config) was added (allowed values are `basic, digest, gssnegotiate, ntlm`) * Added `if_seq_no` / `if_primary_term` to replace `version` for [optimistic concurrency control](https://www.elastic.co/guide/en/elasticsearch/reference/6.8/optimistic-concurrency-control.html) @@ -23,6 +24,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * Added `static_lambda` CS rule [#1870](https://github.com/ruflin/Elastica/pull/1870) * Added `Elastica\Aggregation\DateRange::setTimezone()` [#1847](https://github.com/ruflin/Elastica/pull/1847) * Added endpoint options support to `Elastica\Index::create()` [#1859](https://github.com/ruflin/Elastica/pull/1859) +* Added `Elastica\Aggregation\DateHistogram::setKeyed()` [#1876](https://github.com/ruflin/Elastica/pull/1876) +* Added `Elastica\Aggregation\GeoDistance::setKeyed()` [#1876](https://github.com/ruflin/Elastica/pull/1876) +* Added `Elastica\Aggregation\Histogram::setKeyed()` [#1876](https://github.com/ruflin/Elastica/pull/1876) +* Added `Elastica\Aggregation\IpRange::setKeyed()` [#1876](https://github.com/ruflin/Elastica/pull/1876) ### Changed * Allow `string` such as `wait_for` to be passed to `AbstractUpdateAction::setRefresh` [#1791](https://github.com/ruflin/Elastica/pull/1791) * Changed the return type of `AbstractUpdateAction::getRefresh` to `boolean|string` [#1791](https://github.com/ruflin/Elastica/pull/1791) diff --git a/src/Aggregation/GeoDistance.php b/src/Aggregation/GeoDistance.php index 3905f87993..16cee704a7 100644 --- a/src/Aggregation/GeoDistance.php +++ b/src/Aggregation/GeoDistance.php @@ -11,6 +11,8 @@ */ class GeoDistance extends AbstractAggregation { + use KeyedTrait; + public const DISTANCE_TYPE_ARC = 'arc'; public const DISTANCE_TYPE_PLANE = 'plane'; diff --git a/src/Aggregation/Histogram.php b/src/Aggregation/Histogram.php index f62d1fc150..e837a4fdbb 100644 --- a/src/Aggregation/Histogram.php +++ b/src/Aggregation/Histogram.php @@ -9,6 +9,8 @@ */ class Histogram extends AbstractSimpleAggregation { + use KeyedTrait; + /** * @param string $name the name of this aggregation * @param string $field the name of the field on which to perform the aggregation diff --git a/src/Aggregation/IpRange.php b/src/Aggregation/IpRange.php index b686f1d6e3..dc4855b903 100644 --- a/src/Aggregation/IpRange.php +++ b/src/Aggregation/IpRange.php @@ -11,6 +11,8 @@ */ class IpRange extends AbstractAggregation { + use KeyedTrait; + /** * @param string $name the name of this aggregation * @param string $field the field on which to perform this aggregation diff --git a/src/Aggregation/KeyedTrait.php b/src/Aggregation/KeyedTrait.php new file mode 100644 index 0000000000..2556110a50 --- /dev/null +++ b/src/Aggregation/KeyedTrait.php @@ -0,0 +1,17 @@ +setParam('keyed', $keyed); + } +} diff --git a/src/Aggregation/Percentiles.php b/src/Aggregation/Percentiles.php index ec6275eef6..5534ed430b 100644 --- a/src/Aggregation/Percentiles.php +++ b/src/Aggregation/Percentiles.php @@ -9,6 +9,8 @@ */ class Percentiles extends AbstractSimpleAggregation { + use KeyedTrait; + /** * @param string $name the name of this aggregation * @param string $field the field on which to perform this aggregation @@ -46,18 +48,6 @@ public function setHdr(string $key, float $value): self return $this->setParam('hdr', $compression); } - /** - * the keyed flag is set to true which associates a unique string - * key with each bucket and returns the ranges as a hash - * rather than an array. - * - * @return $this - */ - public function setKeyed(bool $keyed = true): self - { - return $this->setParam('keyed', $keyed); - } - /** * Set which percents must be returned. * diff --git a/src/Aggregation/PercentilesBucket.php b/src/Aggregation/PercentilesBucket.php index 641c2a42fc..e4f56790cb 100644 --- a/src/Aggregation/PercentilesBucket.php +++ b/src/Aggregation/PercentilesBucket.php @@ -11,6 +11,8 @@ */ class PercentilesBucket extends AbstractAggregation { + use KeyedTrait; + /** * @param string $name the name of this aggregation * @param string|null $bucketsPath the field on which to perform this aggregation @@ -69,12 +71,4 @@ public function setPercents(array $percents): self { return $this->setParam('percents', $percents); } - - /** - * Set keyed flag to return the range as an hash instead of an array of key-value pairs. - */ - public function setKeyed(bool $keyed): self - { - return $this->setParam('keyed', $keyed); - } } diff --git a/src/Aggregation/Range.php b/src/Aggregation/Range.php index c090b3e44a..ffc176fba8 100644 --- a/src/Aggregation/Range.php +++ b/src/Aggregation/Range.php @@ -11,6 +11,8 @@ */ class Range extends AbstractSimpleAggregation { + use KeyedTrait; + /** * Add a range to this aggregation. * @@ -45,16 +47,6 @@ public function addRange($fromValue = null, $toValue = null, ?string $key = null return $this->addParam('ranges', $range); } - /** - * If set to true, a unique string key will be associated with each bucket, and ranges will be returned as an associative array. - * - * @return $this - */ - public function setKeyed(bool $keyed): self - { - return $this->setParam('keyed', $keyed); - } - /** * @return $this * diff --git a/tests/Aggregation/DateHistogramTest.php b/tests/Aggregation/DateHistogramTest.php index b7b0c1fa68..5dbf4483d8 100644 --- a/tests/Aggregation/DateHistogramTest.php +++ b/tests/Aggregation/DateHistogramTest.php @@ -39,6 +39,27 @@ public function testDateHistogramAggregation(): void $this->assertEquals(1, $nonDocCount); } + /** + * @group functional + */ + public function testDateHistogramKeyedAggregation(): void + { + $agg = new DateHistogram('hist', 'created', '1h'); + $agg->setKeyed(); + + $query = new Query(); + $query->addAggregation($agg); + $results = $this->_getIndexForTest()->search($query)->getAggregation('hist'); + + $expected = [ + '2014-01-29T00:00:00.000Z', + '2014-01-29T01:00:00.000Z', + '2014-01-29T02:00:00.000Z', + '2014-01-29T03:00:00.000Z', + ]; + $this->assertSame($expected, \array_keys($results['buckets'])); + } + /** * @group unit */ diff --git a/tests/Aggregation/DateRangeTest.php b/tests/Aggregation/DateRangeTest.php index 1a8a95e0df..3aae25a820 100644 --- a/tests/Aggregation/DateRangeTest.php +++ b/tests/Aggregation/DateRangeTest.php @@ -56,6 +56,27 @@ public function testDateRangeAggregation(): void } } + /** + * @group functional + */ + public function testDateRangeKeyedAggregation(): void + { + $agg = new DateRange('date'); + $agg->setField('created'); + $agg->setKeyed(); + $agg->addRange(1390958535000)->addRange(null, 1390958535000); + + $query = new Query(); + $query->addAggregation($agg); + $results = $this->_getIndexForTest()->search($query)->getAggregation('date'); + + $expected = [ + '*-1390958535000', + '1390958535000-*', + ]; + $this->assertSame($expected, \array_keys($results['buckets'])); + } + /** * @group functional */ diff --git a/tests/Aggregation/GeoDistanceTest.php b/tests/Aggregation/GeoDistanceTest.php index 82d84f4904..96c67487f5 100644 --- a/tests/Aggregation/GeoDistanceTest.php +++ b/tests/Aggregation/GeoDistanceTest.php @@ -29,6 +29,26 @@ public function testGeoDistanceAggregation(): void $this->assertEquals(2, $results['buckets'][0]['doc_count']); } + /** + * @group functional + */ + public function testGeoDistanceKeyedAggregation(): void + { + $agg = new GeoDistance('geo', 'location', ['lat' => 32.804654, 'lon' => -117.242594]); + $agg->addRange(null, 100); + $agg->setKeyed(); + $agg->setUnit('mi'); + + $query = new Query(); + $query->addAggregation($agg); + $results = $this->_getIndexForTest()->search($query)->getAggregation('geo'); + + $expected = [ + '*-100.0', + ]; + $this->assertSame($expected, \array_keys($results['buckets'])); + } + protected function _getIndexForTest(): Index { $index = $this->_createIndex(); diff --git a/tests/Aggregation/HistogramTest.php b/tests/Aggregation/HistogramTest.php index e1cd66c584..1753fc582f 100644 --- a/tests/Aggregation/HistogramTest.php +++ b/tests/Aggregation/HistogramTest.php @@ -30,6 +30,29 @@ public function testHistogramAggregation(): void $this->assertEquals(2, $buckets[3]['doc_count']); } + /** + * @group functional + */ + public function testHistogramKeyedAggregation(): void + { + $agg = new Histogram('hist', 'price', 10); + $agg->setMinimumDocumentCount(0); // should return empty buckets + $agg->setKeyed(); + + $query = new Query(); + $query->addAggregation($agg); + $results = $this->_getIndexForTest()->search($query)->getAggregation('hist'); + + $expected = [ + '0.0', + '10.0', + '20.0', + '30.0', + '40.0', + ]; + $this->assertSame($expected, \array_keys($results['buckets'])); + } + protected function _getIndexForTest(): Index { $index = $this->_createIndex(); diff --git a/tests/Aggregation/IpRangeTest.php b/tests/Aggregation/IpRangeTest.php index abb25b485b..5509a838bb 100644 --- a/tests/Aggregation/IpRangeTest.php +++ b/tests/Aggregation/IpRangeTest.php @@ -40,6 +40,31 @@ public function testIpRangeAggregation(): void } } + /** + * @group functional + */ + public function testIpRangeKeyedAggregation(): void + { + $agg = new IpRange('ip', 'address'); + $agg->addRange('192.168.1.101'); + $agg->addRange(null, '192.168.1.200'); + $agg->setKeyed(); + + $cidrRange = '192.168.1.0/24'; + $agg->addMaskRange($cidrRange); + + $query = new Query(); + $query->addAggregation($agg); + $results = $this->_getIndexForTest()->search($query)->getAggregation('ip'); + + $expected = [ + '*-192.168.1.200', + '192.168.1.0/24', + '192.168.1.101-*', + ]; + $this->assertSame($expected, \array_keys($results['buckets'])); + } + protected function _getIndexForTest(): Index { $index = $this->_createIndex(); diff --git a/tests/Aggregation/RangeTest.php b/tests/Aggregation/RangeTest.php index a7b484a746..d138a20637 100644 --- a/tests/Aggregation/RangeTest.php +++ b/tests/Aggregation/RangeTest.php @@ -28,6 +28,26 @@ public function testRangeAggregation(): void $this->assertEquals(2, $results['buckets'][0]['doc_count']); } + /** + * @group functional + */ + public function testRangeKeyedAggregation(): void + { + $agg = new Range('range'); + $agg->setField('price'); + $agg->addRange(1.5, 5); + $agg->setKeyed(); + + $query = new Query(); + $query->addAggregation($agg); + $results = $this->_getIndexForTest()->search($query)->getAggregation('range'); + + $expected = [ + '1.5-5.0', + ]; + $this->assertSame($expected, \array_keys($results['buckets'])); + } + /** * @group unit */