Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add Extended Stats Bucket #1756

Merged
merged 13 commits into from
Mar 5, 2020
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* Added `Elastica\Reindex->setQuery(Elastica\Query\AbstractQuery $query): void` [#1752](https://github.com/ruflin/Elastica/pull/1752)
* Added constants `PIPELINE`, `REFRESH_TRUE`, `REFRESH_FALSE`, `REFRESH_WAIT_FOR`, `SLICES` and `SLICES_AUTO` to `Elastica\Reindex` [#1752](https://github.com/ruflin/Elastica/pull/1752)
* Added `Elastica\Pipeline->getId(): ?string` [#1752](https://github.com/ruflin/Elastica/pull/1752)
* Added `Elastica\Aggregation\ExtendedStatsBucket` aggregation [#1756](https://github.com/ruflin/Elastica/pull/1756)

### Changed
- Updated PHP coding standards to adhere to PSR-12 [#1760](https://github.com/ruflin/Elastica/pull/1760)
Expand Down
37 changes: 37 additions & 0 deletions src/Aggregation/ExtendedStatsBucket.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

namespace Elastica\Aggregation;

/**
* Implements a Extended Stats Bucket Aggregation.
*
* @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-pipeline-extended-stats-bucket-aggregation.html
*/
class ExtendedStatsBucket extends AbstractAggregation
{
public function __construct(string $name, string $bucketsPath)
{
parent::__construct($name);
$this->setBucketsPath($bucketsPath);
}

public function setBucketsPath(string $bucketsPath): self
{
return $this->setParam('buckets_path', $bucketsPath);
}

public function setGapPolicy(string $gapPolicy): self
{
return $this->setParam('gap_policy', $gapPolicy);
}

public function setFormat(string $format): self
{
return $this->setParam('format', $format);
}

public function setSigma(int $sigma): self
{
return $this->setParam('sigma', $sigma);
}
}
84 changes: 84 additions & 0 deletions tests/Aggregation/ExtendedStatsBucketTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<?php

namespace Elastica\Test\Aggregation;

use Elastica\Aggregation\ExtendedStatsBucket;
use Elastica\Aggregation\Histogram;
use Elastica\Aggregation\Max;
use Elastica\Document;
use Elastica\Index;
use Elastica\Query;

/**
* @internal
*/
class ExtendedStatsBucketTest extends BaseAggregationTest
{
/**
* @group functional
*/
public function testExtendedStatBucketAggregation(): void
{
$bucketScriptAggregation = new ExtendedStatsBucket('result', 'age_groups>max_weight');

$histogramAggregation = new Histogram('age_groups', 'age', 10);

$histogramAggregation->addAggregation((new Max('max_weight'))->setField('weight'));

$query = Query::create([])
->addAggregation($histogramAggregation)
->addAggregation($bucketScriptAggregation)
;

$results = $this->_getIndexForTest()->search($query)->getAggregation('result');

$this->assertEquals(3, $results['count']);
$this->assertEquals(50, $results['min']);
$this->assertEquals(70, $results['max']);
$this->assertEquals(60, $results['avg']);
$this->assertEquals(180, $results['sum']);
$this->assertEquals(11000, $results['sum_of_squares']);
$this->assertEquals(66.66666666666667, $results['variance']);
$this->assertEquals(8.16496580927726, $results['std_deviation']);
$this->assertEquals(['upper' => 76.32993161855453, 'lower' => 43.670068381445475], $results['std_deviation_bounds']);
}

/**
* @group unit
*/
public function testOverrideBucketsPathThroughSetters(): void
{
$serialDiffAgg = new ExtendedStatsBucket('bucket_part', 'foobar');

$serialDiffAgg
->setBucketsPath('age_groups>max_weight')
->setFormat('test_format')
->setGapPolicy(10)
;

$expected = [
'extended_stats_bucket' => [
'buckets_path' => 'age_groups>max_weight',
'format' => 'test_format',
'gap_policy' => 10,
],
];

$this->assertEquals($expected, $serialDiffAgg->toArray());
}

private function _getIndexForTest(): Index
{
$index = $this->_createIndex();

$index->addDocuments([
Document::create(['weight' => 60, 'height' => 180, 'age' => 25]),
Document::create(['weight' => 70, 'height' => 156, 'age' => 32]),
Document::create(['weight' => 50, 'height' => 155, 'age' => 45]),
]);

$index->refresh();

return $index;
}
}