Skip to content

Commit

Permalink
Add avg_bucket & sum_bucket to aggregations
Browse files Browse the repository at this point in the history
  • Loading branch information
Josselin Henrot committed Jan 26, 2018
1 parent a00e6b7 commit 13a75ce
Show file tree
Hide file tree
Showing 7 changed files with 361 additions and 2 deletions.
5 changes: 3 additions & 2 deletions CHANGELOG.md
Expand Up @@ -4,7 +4,7 @@ All notable changes to this project will be documented in this file based on the
## [Unreleased](https://github.com/ruflin/Elastica/compare/5.3.0...master)

### Backward Compatibility Breaks

### Bugfixes

### Added
Expand All @@ -23,14 +23,15 @@ All notable changes to this project will be documented in this file based on the
### Backward Compatibility Breaks

- Removed `Query\NumericRange`, use `Query\Range` instead [#1334](https://github.com/ruflin/Elastica/pull/1334)

### Bugfixes

- Send the `scroll_id` inside a json body instead of plain text [#1325](https://github.com/ruflin/Elastica/pull/1325)

### Added
- Added getNumberOfReplicas() for index settings [PR#1324](https://github.com/ruflin/Elastica/pull/1324)
- Added getNumberOfShards() for index settings [PR#1321](https://github.com/ruflin/Elastica/pull/1331)
- Added avg_bucket() and sum_bucket() in aggregations [PR#1443](https://github.com/ruflin/Elastica/pull/1443) - (https://github.com/ruflin/Elastica/issues/1279)


## [5.2.1](https://github.com/ruflin/Elastica/compare/5.2.0...5.2.1)
Expand Down
75 changes: 75 additions & 0 deletions lib/Elastica/Aggregation/AvgBucket.php
@@ -0,0 +1,75 @@
<?php
namespace Elastica\Aggregation;

use Elastica\Exception\InvalidException;

/**
* Class AvgBucket.
*
* @link https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-pipeline-avg-bucket-aggregation.html
*/
class AvgBucket extends AbstractAggregation
{
/**
* @param string $name
* @param array|null $bucketsPath
*/
public function __construct($name, $bucketsPath = null)
{
parent::__construct($name);

if ($bucketsPath !== null) {
$this->setBucketsPath($bucketsPath);
}
}

/**
* Set the buckets_path for this aggregation.
*
* @param string $bucketsPath
*
* @return $this
*/
public function setBucketsPath($bucketsPath)
{
return $this->setParam('buckets_path', $bucketsPath);
}

/**
* Set the gap policy for this aggregation.
*
* @param string $gapPolicy
*
* @return $this
*/
public function setGapPolicy($gapPolicy)
{
return $this->setParam('gap_policy', $gapPolicy);
}

/**
* Set the format for this aggregation.
*
* @param string $format
*
* @return $this
*/
public function setFormat($format)
{
return $this->setParam('format', $format);
}

/**
* @throws InvalidException If buckets path or script is not set
*
* @return array
*/
public function toArray()
{
if (!$this->hasParam('buckets_path')) {
throw new InvalidException('Buckets path is required');
}

return parent::toArray();
}
}
75 changes: 75 additions & 0 deletions lib/Elastica/Aggregation/SumBucket.php
@@ -0,0 +1,75 @@
<?php
namespace Elastica\Aggregation;

use Elastica\Exception\InvalidException;

/**
* Class SumBucket.
*
* @link https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-pipeline-sum-bucket-aggregation.html
*/
class SumBucket extends AbstractAggregation
{
/**
* @param string $name
* @param array|null $bucketsPath
*/
public function __construct($name, $bucketsPath = null)
{
parent::__construct($name);

if ($bucketsPath !== null) {
$this->setBucketsPath($bucketsPath);
}
}

/**
* Set the buckets_path for this aggregation.
*
* @param string $bucketsPath
*
* @return $this
*/
public function setBucketsPath($bucketsPath)
{
return $this->setParam('buckets_path', $bucketsPath);
}

/**
* Set the gap policy for this aggregation.
*
* @param string $gapPolicy
*
* @return $this
*/
public function setGapPolicy($gapPolicy)
{
return $this->setParam('gap_policy', $gapPolicy);
}

/**
* Set the format for this aggregation.
*
* @param string $format
*
* @return $this
*/
public function setFormat($format)
{
return $this->setParam('format', $format);
}

/**
* @throws InvalidException If buckets path or script is not set
*
* @return array
*/
public function toArray()
{
if (!$this->hasParam('buckets_path')) {
throw new InvalidException('Buckets path is required');
}

return parent::toArray();
}
}
32 changes: 32 additions & 0 deletions lib/Elastica/QueryBuilder/DSL/Aggregation.php
Expand Up @@ -2,6 +2,7 @@
namespace Elastica\QueryBuilder\DSL;

use Elastica\Aggregation\Avg;
use Elastica\Aggregation\AvgBucket;
use Elastica\Aggregation\BucketScript;
use Elastica\Aggregation\Cardinality;
use Elastica\Aggregation\DateHistogram;
Expand All @@ -26,6 +27,7 @@
use Elastica\Aggregation\SignificantTerms;
use Elastica\Aggregation\Stats;
use Elastica\Aggregation\Sum;
use Elastica\Aggregation\SumBucket;
use Elastica\Aggregation\Terms;
use Elastica\Aggregation\TopHits;
use Elastica\Aggregation\ValueCount;
Expand Down Expand Up @@ -94,6 +96,21 @@ public function sum($name)
return new Sum($name);
}

/**
* sum bucket aggregation.
*
* @link https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-pipeline-sum-bucket-aggregation.html
*
* @param string $name
* @param array|null $bucketsPath
*
* @return SumBucket
*/
public function sum_bucket($name, $bucketsPath = null)
{
return new SumBucket($name, $bucketsPath);
}

/**
* avg aggregation.
*
Expand All @@ -108,6 +125,21 @@ public function avg($name)
return new Avg($name);
}

/**
* avg bucket aggregation.
*
* @link https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-pipeline-avg-bucket-aggregation.html
*
* @param string $name
* @param array|null $bucketsPath
*
* @return AvgBucket
*/
public function avg_bucket($name, $bucketsPath = null)
{
return new AvgBucket($name, $bucketsPath);
}

/**
* stats aggregation.
*
Expand Down
2 changes: 2 additions & 0 deletions lib/Elastica/QueryBuilder/Version/Version240.php
Expand Up @@ -53,7 +53,9 @@ class Version240 extends Version
'min',
'max',
'sum',
'sum_bucket',
'avg',
'avg_bucket',
'stats',
'extended_stats',
'value_count',
Expand Down
87 changes: 87 additions & 0 deletions test/Elastica/Aggregation/AvgBucketTest.php
@@ -0,0 +1,87 @@
<?php
namespace Elastica\Test\Aggregation;

use Elastica\Aggregation\AvgBucket;
use Elastica\Aggregation\Avg;
use Elastica\Aggregation\Terms;
use Elastica\Document;
use Elastica\Query;

class AvgBucketTest extends BaseAggregationTest
{
protected function _getIndexForTest()
{
$index = $this->_createIndex();

$index->getType('test')->addDocuments([
Document::create(['page' => 1, 'likes' => 180]),
Document::create(['page' => 1, 'likes' => 156]),
Document::create(['page' => 2, 'likes' => 155]),
]);

$index->refresh();

return $index;
}

/**
* @group functional
*/
public function testAvgBucketAggregation()
{
$this->_checkScriptInlineSetting();

$avgBucketAggregation = new AvgBucket(
'avg_likes_by_page',
'pages > avg_likes'
);

$sumLikes = new Avg('avg_likes');
$sumLikes->setField('likes');

$groupByPage = new Terms('pages');
$groupByPage
->setField('page')
->setSize(2)
->addAggregation($sumLikes);

$query = Query::create([])->addAggregation($groupByPage)->addAggregation($avgBucketAggregation);

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

$this->assertEquals(161.5, $results['value']);
}

/**
* @group unit
*/
public function testConstructThroughSetters()
{
$serialDiffAgg = new AvgBucket('avg_bucket');

$serialDiffAgg
->setBucketsPath('pages > avg_likes_by_page')
->setFormat('test_format')
->setGapPolicy(10);

$expected = [
'avg_bucket' => [
'buckets_path' => 'pages > avg_likes_by_page',
'format' => 'test_format',
'gap_policy' => 10,
],
];

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

/**
* @group unit
* @expectedException InvalidException
*/
public function testToArrayInvalidBucketsPath()
{
$serialDiffAgg = new AvgBucket('avg_bucket');
$serialDiffAgg->toArray();
}
}

0 comments on commit 13a75ce

Please sign in to comment.