From 8116ee753e8ab231323694a3c7e3c63fb1e47885 Mon Sep 17 00:00:00 2001 From: Federico Panini Date: Sun, 11 Nov 2018 14:43:18 +0100 Subject: [PATCH] update old implementations on Percentiles Aggregation (compression, hdr) --- CHANGELOG.md | 21 ++- lib/Elastica/Aggregation/Percentiles.php | 58 +++++++- test/Elastica/Aggregation/PercentilesTest.php | 140 +++++++++++++++++- 3 files changed, 204 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0208cb282c..2abbe9466d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,26 @@ All notable changes to this project will be documented in this file based on the * `\Elastica\ResultSet::next` returns `void` instead of `\Elastica\Result|false` * `\Elastica\Bulk\ResponseSet::current` returns `\Elastica\Bulk\Response` instead of `\Elastica\Bulk\Response|false` * `\Elastica\Multi\ResultSet::current` returns `\Elastica\ResultSet` instead of `\Elastica\ResultSet|false` -* Aggreation\Percentiles updated to a newer version of the Algorithm (T-Digest 3.2) and Percentiles results changed a bit Have a [look at here](https://github.com/elastic/elasticsearch/pull/28305), so updated tests in order not to fail. [#1531]([#1352](https://github.com/ruflin/Elastica/pull/1531)) +* `Aggreation\Percentiles` updated to a newer version of the Algorithm (T-Digest 3.2) and Percentiles results changed a bit Have a [look at here](https://github.com/elastic/elasticsearch/pull/28305), so updated tests in order not to fail. [#1531]([#1352](https://github.com/ruflin/Elastica/pull/1531)) +* `Aggregation\Percentiles` have been updated since [Elasticsearch 2.3](https://www.elastic.co/guide/en/elasticsearch/reference/2.3/search-aggregations-metrics-percentile-aggregation.html). In this version `compression, HDR histogram` changed their implementations. The `missing` field has never been implemented. [#1532](https://github.com/ruflin/Elastica/pull/1532) + + Before + ```json + "compression" : 200, + "method" : "hdr", + "number_of_significant_value_digits" : 3 + ``` + + Now + ```json + "tdigest": { + "compression" : 200 + }, + "hdr": { + "number_of_significant_value_digits" : 3 + } + ``` +* Never implemented the method *Missing* on [`Aggregation\Percentiles`](https://www.elastic.co/guide/en/elasticsearch/reference/6.4/search-aggregations-metrics-percentile-aggregation.html) ### Bugfixes diff --git a/lib/Elastica/Aggregation/Percentiles.php b/lib/Elastica/Aggregation/Percentiles.php index 87ec9a10d7..f8386dafb5 100644 --- a/lib/Elastica/Aggregation/Percentiles.php +++ b/lib/Elastica/Aggregation/Percentiles.php @@ -26,11 +26,40 @@ public function __construct($name, $field = null) * * @param float $value * - * @return $this + * @return Percentiles $this */ - public function setCompression($value) + public function setCompression(float $value): Percentiles { - return $this->setParam('compression', (float) $value); + $compression = array('compression' => $value); + return $this->setParam('tdigest', $compression); + } + + /** + * Set hdr parameter. + * + * @param string $key + * @param float $value + * + * @return Percentiles $this + */ + public function setHdr(string $key, float $value): Percentiles + { + $compression = array($key => $value); + 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 + * + * @param bool $keyed + * + * @return Percentiles $this + */ + public function setKeyed(bool $keyed = true): Percentiles + { + return $this->setParam('keyed', $keyed); } /** @@ -38,9 +67,9 @@ public function setCompression($value) * * @param float[] $percents * - * @return $this + * @return Percentiles $this */ - public function setPercents(array $percents) + public function setPercents(array $percents): Percentiles { return $this->setParam('percents', $percents); } @@ -50,10 +79,23 @@ public function setPercents(array $percents) * * @param float $percent * - * @return $this + * @return Percentiles $this + */ + public function addPercent(float $percent): Percentiles + { + return $this->addParam('percents', $percent); + } + + /** + * Defines how documents that are missing a value should + * be treated + * + * @param float $missing + * + * @return Percentiles */ - public function addPercent($percent) + public function setMissing(float $missing): Percentiles { - return $this->addParam('percents', (float) $percent); + return $this->setParam('missing', $missing); } } diff --git a/test/Elastica/Aggregation/PercentilesTest.php b/test/Elastica/Aggregation/PercentilesTest.php index 82a55e4aa4..16a084d0f1 100644 --- a/test/Elastica/Aggregation/PercentilesTest.php +++ b/test/Elastica/Aggregation/PercentilesTest.php @@ -32,16 +32,51 @@ public function testSetField() } /** - * @group functional + * @group unit */ - public function testSetCompression() + public function testCompression() { + $expected = [ + 'percentiles' => [ + 'field' => 'price', + 'keyed' => false, + 'tdigest' => [ + 'compression' => 100 + ] + ] + + ]; $aggr = new Percentiles('price_percentile'); - $aggr->setCompression(200); - $this->assertEquals(200, $aggr->getParam('compression')); - $this->assertInstanceOf(Percentiles::class, $aggr->setCompression(200)); + $aggr->setField('price'); + $aggr->setKeyed(false); + $aggr->setCompression(100); + + $this->assertEquals($expected, $aggr->toArray()); } + /** + * @group unit + */ + public function testHdr() + { + $expected = [ + 'percentiles' => [ + 'field' => 'price', + 'keyed' => false, + 'hdr' => [ + 'number_of_significant_value_digits' => 2.0 + ] + ] + + ]; + $aggr = new Percentiles('price_percentile'); + $aggr->setField('price'); + $aggr->setKeyed(false); + $aggr->setHdr('number_of_significant_value_digits', 2); + + $this->assertEquals($expected, $aggr->toArray()); + } + /** * @group functional */ @@ -86,7 +121,6 @@ public function testSetScript() */ public function testActualWork() { - // prepare $index = $this->_createIndex(); $type = $index->getType('offer'); @@ -122,4 +156,98 @@ public function testActualWork() $this->assertEquals(1000.0, $aggrResult['values']['95.0']); $this->assertEquals(1000.0, $aggrResult['values']['99.0']); } + + /** + * @group functional + */ + public function testKeyed() + { + $expected = [ + 'values' => [ + [ + 'key' => 1, + 'value' => 100 + ], + [ + 'key' => 5, + 'value' => 100 + ], + [ + 'key' => 25, + 'value' => 300 + ], + [ + 'key' => 50, + 'value' => 550 + ], + [ + 'key' => 75, + 'value' => 800 + ], + [ + 'key' => 95, + 'value' => 1000 + ], + [ + 'key' => 99, + 'value' => 1000 + ] + ] + ]; + + // prepare + $index = $this->_createIndex(); + $type = $index->getType('offer'); + $type->addDocuments([ + new Document(1, ['price' => 100]), + new Document(2, ['price' => 200]), + new Document(3, ['price' => 300]), + new Document(4, ['price' => 400]), + new Document(5, ['price' => 500]), + new Document(6, ['price' => 600]), + new Document(7, ['price' => 700]), + new Document(8, ['price' => 800]), + new Document(9, ['price' => 900]), + new Document(10, ['price' => 1000]), + ]); + $index->refresh(); + + // execute + $aggr = new Percentiles('price_percentile'); + $aggr->setField('price'); + $aggr->setKeyed(false); + + $query = new Query(); + $query->addAggregation($aggr); + + $resultSet = $type->search($query); + $aggrResult = $resultSet->getAggregation('price_percentile'); + + $this->assertEquals($expected, $aggrResult); + } + + /** + * @group unit + */ + public function testMissing() + { + $expected = [ + 'percentiles' => [ + 'field' => 'price', + 'keyed' => false, + 'hdr' => [ + 'number_of_significant_value_digits' => 2.0 + ], + 'missing' => 10 + ] + + ]; + $aggr = new Percentiles('price_percentile'); + $aggr->setField('price'); + $aggr->setKeyed(false); + $aggr->setHdr('number_of_significant_value_digits', 2); + $aggr->setMissing(10); + + $this->assertEquals($expected, $aggr->toArray()); + } }