Skip to content

Commit 1f094b7

Browse files
p365labsruflin
authored andcommitted
Missing implementations on Percentiles Aggregation (compression, hdr) (#1532)
`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). Since this version these fields has changed implementation: - compression - HDR histogram The `missing` field has never been implemented.
1 parent 220b9dc commit 1f094b7

File tree

3 files changed

+204
-15
lines changed

3 files changed

+204
-15
lines changed

CHANGELOG.md

+20-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,26 @@ All notable changes to this project will be documented in this file based on the
99
* `\Elastica\ResultSet::next` returns `void` instead of `\Elastica\Result|false`
1010
* `\Elastica\Bulk\ResponseSet::current` returns `\Elastica\Bulk\Response` instead of `\Elastica\Bulk\Response|false`
1111
* `\Elastica\Multi\ResultSet::current` returns `\Elastica\ResultSet` instead of `\Elastica\ResultSet|false`
12-
* 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))
12+
* `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))
13+
* `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)
14+
15+
Before
16+
```json
17+
"compression" : 200,
18+
"method" : "hdr",
19+
"number_of_significant_value_digits" : 3
20+
```
21+
22+
Now
23+
```json
24+
"tdigest": {
25+
"compression" : 200
26+
},
27+
"hdr": {
28+
"number_of_significant_value_digits" : 3
29+
}
30+
```
31+
* Never implemented the method *Missing* on [`Aggregation\Percentiles`](https://www.elastic.co/guide/en/elasticsearch/reference/6.4/search-aggregations-metrics-percentile-aggregation.html)
1332

1433
### Bugfixes
1534

lib/Elastica/Aggregation/Percentiles.php

+50-8
Original file line numberDiff line numberDiff line change
@@ -26,21 +26,50 @@ public function __construct($name, $field = null)
2626
*
2727
* @param float $value
2828
*
29-
* @return $this
29+
* @return Percentiles $this
3030
*/
31-
public function setCompression($value)
31+
public function setCompression(float $value): Percentiles
3232
{
33-
return $this->setParam('compression', (float) $value);
33+
$compression = array('compression' => $value);
34+
return $this->setParam('tdigest', $compression);
35+
}
36+
37+
/**
38+
* Set hdr parameter.
39+
*
40+
* @param string $key
41+
* @param float $value
42+
*
43+
* @return Percentiles $this
44+
*/
45+
public function setHdr(string $key, float $value): Percentiles
46+
{
47+
$compression = array($key => $value);
48+
return $this->setParam('hdr', $compression);
49+
}
50+
51+
/**
52+
* the keyed flag is set to true which associates a unique string
53+
* key with each bucket and returns the ranges as a hash
54+
* rather than an array
55+
*
56+
* @param bool $keyed
57+
*
58+
* @return Percentiles $this
59+
*/
60+
public function setKeyed(bool $keyed = true): Percentiles
61+
{
62+
return $this->setParam('keyed', $keyed);
3463
}
3564

3665
/**
3766
* Set which percents must be returned.
3867
*
3968
* @param float[] $percents
4069
*
41-
* @return $this
70+
* @return Percentiles $this
4271
*/
43-
public function setPercents(array $percents)
72+
public function setPercents(array $percents): Percentiles
4473
{
4574
return $this->setParam('percents', $percents);
4675
}
@@ -50,10 +79,23 @@ public function setPercents(array $percents)
5079
*
5180
* @param float $percent
5281
*
53-
* @return $this
82+
* @return Percentiles $this
83+
*/
84+
public function addPercent(float $percent): Percentiles
85+
{
86+
return $this->addParam('percents', $percent);
87+
}
88+
89+
/**
90+
* Defines how documents that are missing a value should
91+
* be treated
92+
*
93+
* @param float $missing
94+
*
95+
* @return Percentiles
5496
*/
55-
public function addPercent($percent)
97+
public function setMissing(float $missing): Percentiles
5698
{
57-
return $this->addParam('percents', (float) $percent);
99+
return $this->setParam('missing', $missing);
58100
}
59101
}

test/Elastica/Aggregation/PercentilesTest.php

+134-6
Original file line numberDiff line numberDiff line change
@@ -32,16 +32,51 @@ public function testSetField()
3232
}
3333

3434
/**
35-
* @group functional
35+
* @group unit
3636
*/
37-
public function testSetCompression()
37+
public function testCompression()
3838
{
39+
$expected = [
40+
'percentiles' => [
41+
'field' => 'price',
42+
'keyed' => false,
43+
'tdigest' => [
44+
'compression' => 100
45+
]
46+
]
47+
48+
];
3949
$aggr = new Percentiles('price_percentile');
40-
$aggr->setCompression(200);
41-
$this->assertEquals(200, $aggr->getParam('compression'));
42-
$this->assertInstanceOf(Percentiles::class, $aggr->setCompression(200));
50+
$aggr->setField('price');
51+
$aggr->setKeyed(false);
52+
$aggr->setCompression(100);
53+
54+
$this->assertEquals($expected, $aggr->toArray());
4355
}
4456

57+
/**
58+
* @group unit
59+
*/
60+
public function testHdr()
61+
{
62+
$expected = [
63+
'percentiles' => [
64+
'field' => 'price',
65+
'keyed' => false,
66+
'hdr' => [
67+
'number_of_significant_value_digits' => 2.0
68+
]
69+
]
70+
71+
];
72+
$aggr = new Percentiles('price_percentile');
73+
$aggr->setField('price');
74+
$aggr->setKeyed(false);
75+
$aggr->setHdr('number_of_significant_value_digits', 2);
76+
77+
$this->assertEquals($expected, $aggr->toArray());
78+
}
79+
4580
/**
4681
* @group functional
4782
*/
@@ -86,7 +121,6 @@ public function testSetScript()
86121
*/
87122
public function testActualWork()
88123
{
89-
90124
// prepare
91125
$index = $this->_createIndex();
92126
$type = $index->getType('offer');
@@ -122,4 +156,98 @@ public function testActualWork()
122156
$this->assertEquals(1000.0, $aggrResult['values']['95.0']);
123157
$this->assertEquals(1000.0, $aggrResult['values']['99.0']);
124158
}
159+
160+
/**
161+
* @group functional
162+
*/
163+
public function testKeyed()
164+
{
165+
$expected = [
166+
'values' => [
167+
[
168+
'key' => 1,
169+
'value' => 100
170+
],
171+
[
172+
'key' => 5,
173+
'value' => 100
174+
],
175+
[
176+
'key' => 25,
177+
'value' => 300
178+
],
179+
[
180+
'key' => 50,
181+
'value' => 550
182+
],
183+
[
184+
'key' => 75,
185+
'value' => 800
186+
],
187+
[
188+
'key' => 95,
189+
'value' => 1000
190+
],
191+
[
192+
'key' => 99,
193+
'value' => 1000
194+
]
195+
]
196+
];
197+
198+
// prepare
199+
$index = $this->_createIndex();
200+
$type = $index->getType('offer');
201+
$type->addDocuments([
202+
new Document(1, ['price' => 100]),
203+
new Document(2, ['price' => 200]),
204+
new Document(3, ['price' => 300]),
205+
new Document(4, ['price' => 400]),
206+
new Document(5, ['price' => 500]),
207+
new Document(6, ['price' => 600]),
208+
new Document(7, ['price' => 700]),
209+
new Document(8, ['price' => 800]),
210+
new Document(9, ['price' => 900]),
211+
new Document(10, ['price' => 1000]),
212+
]);
213+
$index->refresh();
214+
215+
// execute
216+
$aggr = new Percentiles('price_percentile');
217+
$aggr->setField('price');
218+
$aggr->setKeyed(false);
219+
220+
$query = new Query();
221+
$query->addAggregation($aggr);
222+
223+
$resultSet = $type->search($query);
224+
$aggrResult = $resultSet->getAggregation('price_percentile');
225+
226+
$this->assertEquals($expected, $aggrResult);
227+
}
228+
229+
/**
230+
* @group unit
231+
*/
232+
public function testMissing()
233+
{
234+
$expected = [
235+
'percentiles' => [
236+
'field' => 'price',
237+
'keyed' => false,
238+
'hdr' => [
239+
'number_of_significant_value_digits' => 2.0
240+
],
241+
'missing' => 10
242+
]
243+
244+
];
245+
$aggr = new Percentiles('price_percentile');
246+
$aggr->setField('price');
247+
$aggr->setKeyed(false);
248+
$aggr->setHdr('number_of_significant_value_digits', 2);
249+
$aggr->setMissing(10);
250+
251+
$this->assertEquals($expected, $aggr->toArray());
252+
}
125253
}

0 commit comments

Comments
 (0)