diff --git a/docs/Aggregation/Pipeline/BucketScript.md b/docs/Aggregation/Pipeline/BucketScript.md new file mode 100644 index 0000000000000000000000000000000000000000..689b4b9cde4fcff6afbec9cbe6da0bcee947950b --- /dev/null +++ b/docs/Aggregation/Pipeline/BucketScript.md @@ -0,0 +1,88 @@ +# Bucket Script Aggregation + +> More info bucket script aggregation is in the [official elasticsearch docs][1] + +A parent pipeline aggregation which executes a script which can perform per bucket +computations on specified metrics in the parent multi-bucket aggregation. The specified +metric must be numeric and the script must return a numeric value. + +## Simple example + +```JSON +{ + "aggs" : { + "sales_per_month" : { + "date_histogram" : { + "field" : "date", + "interval" : "month" + }, + "aggs": { + "total_sales": { + "sum": { + "field": "price" + } + }, + "t-shirts": { + "filter": { + "term": { + "type": "t-shirt" + } + }, + "aggs": { + "sales": { + "sum": { + "field": "price" + } + } + } + }, + "t-shirt-percentage": { + "bucket_script": { + "buckets_path": { + "tShirtSales": "t-shirts>sales", + "totalSales": "total_sales" + }, + "script": "tShirtSales / totalSales * 100" + } + } + } + } + } +} +``` + +And now the query via DSL: + +```php +$search = new Search(); + +$dateAggregation = new DateHistogramAggregation('sales_per_month', 'date', 'month'); +$sumAggregation = new SumAggregation('total_sales', 'price'); +$filterAggregation = new FilterAggregation( + 't-shirts', + new TermQuery('type', 't-shirt') +); +$filterAggregation->addAggregation( + new SumAggregation('ales', 'price') +); +$dateAggregation->addAggregation( + +); +$scriptAggregation = new BucketScriptAggregation( + 't-shirt-percentage', + [ + 'tShirtSales' => 't-shirts>sales', + 'totalSales' => 'total_sales', + ] +); +$scriptAggregation->setScript('tShirtSales / totalSales * 100'); +$dateAggregation->addAggregation($sumAggregation); +$dateAggregation->addAggregation($filterAggregation); +$dateAggregation->addAggregation($scriptAggregation); + +$search->addAggregation($dateAggregation); + +$aggArray = $search->toArray(); +``` + +[1]: https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-pipeline-bucket-script-aggregation.html \ No newline at end of file diff --git a/docs/Aggregation/Pipeline/BucketSelector.md b/docs/Aggregation/Pipeline/BucketSelector.md new file mode 100644 index 0000000000000000000000000000000000000000..c206102c560f0a9ec31da097c90967f4bd8fa469 --- /dev/null +++ b/docs/Aggregation/Pipeline/BucketSelector.md @@ -0,0 +1,62 @@ +# Bucket Selector Aggregation + +> More info bucket selector aggregation is in the [official elasticsearch docs][1] + +A parent pipeline aggregation which executes a script which determines whether the +current bucket will be retained in the parent multi-bucket aggregation. The specified +metric must be numeric and the script must return a boolean value. If the script +language is expression then a numeric return value is permitted. In this case 0.0 will +be evaluated as false and all other values will evaluate to true. + +## Simple example + +```JSON +{ + "aggs" : { + "sales_per_month" : { + "date_histogram" : { + "field" : "date", + "interval" : "month" + }, + "aggs": { + "total_sales": { + "sum": { + "field": "price" + } + }, + "sales_bucket_filter": { + "bucket_selector": { + "buckets_path": { + "totalSales": "total_sales" + }, + "script": "totalSales <= 50" + } + } + } + } + } +} +``` + +And now the query via DSL: + +```php +$search = new Search(); + +$dateAggregation = new DateHistogramAggregation('sales_per_month', 'date', 'month'); +$dateAggregation->addAggregation( + new SumAggregation('total_sales', 'price'); +); +$scriptAggregation = new BucketSelectorAggregation( + 'sales_bucket_filter', + ['totalSales' => 'total_sales'] +); +$scriptAggregation->setScript('totalSales <= 50'); +$dateAggregation->addAggregation($scriptAggregation); + +$search->addAggregation($dateAggregation); + +$aggArray = $search->toArray(); +``` + +[1]: https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-pipeline-bucket-selector-aggregation.html \ No newline at end of file diff --git a/src/Aggregation/Pipeline/BucketScriptAggregation.php b/src/Aggregation/Pipeline/BucketScriptAggregation.php new file mode 100644 index 0000000000000000000000000000000000000000..ac1d90ac343119dbf9cd040883963c95082a6d6f --- /dev/null +++ b/src/Aggregation/Pipeline/BucketScriptAggregation.php @@ -0,0 +1,82 @@ +<?php + +/* + * This file is part of the ONGR package. + * + * (c) NFQ Technologies UAB <info@nfq.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace ONGR\ElasticsearchDSL\Aggregation\Pipeline; + +/** + * Class representing Bucket Script Pipeline Aggregation. + * + * @link https://goo.gl/miVxcx + */ +class BucketScriptAggregation extends AbstractPipelineAggregation +{ + /** + * @var string + */ + private $script; + + /** + * @param string $name + * @param array $bucketsPath + * @param string $script + */ + public function __construct($name, $bucketsPath, $script = null) + { + parent::__construct($name, $bucketsPath); + $this->setScript($script); + } + + /** + * @return string + */ + public function getScript() + { + return $this->script; + } + + /** + * @param string $script + */ + public function setScript($script) + { + $this->script = $script; + } + + /** + * {@inheritdoc} + */ + public function getType() + { + return 'bucket_script'; + } + + /** + * {@inheritdoc} + */ + public function getArray() + { + if (!$this->getScript()) { + throw new \LogicException( + sprintf( + '`%s` aggregation must have script set.', + $this->getName() + ) + ); + } + + $out = [ + 'buckets_path' => $this->getBucketsPath(), + 'script' => $this->getScript(), + ]; + + return $out; + } +} diff --git a/src/Aggregation/Pipeline/BucketSelectorAggregation.php b/src/Aggregation/Pipeline/BucketSelectorAggregation.php new file mode 100644 index 0000000000000000000000000000000000000000..cd8c41b328c4d5ce685031cb24d1ec27217da2c9 --- /dev/null +++ b/src/Aggregation/Pipeline/BucketSelectorAggregation.php @@ -0,0 +1,28 @@ +<?php + +/* + * This file is part of the ONGR package. + * + * (c) NFQ Technologies UAB <info@nfq.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace ONGR\ElasticsearchDSL\Aggregation\Pipeline; + +/** + * Class representing Bucket Selector Pipeline Aggregation. + * + * @link https://goo.gl/IQbyyM + */ +class BucketSelectorAggregation extends BucketScriptAggregation +{ + /** + * {@inheritdoc} + */ + public function getType() + { + return 'bucket_selector'; + } +} diff --git a/tests/Aggregation/Pipeline/BucketScriptAggregationTest.php b/tests/Aggregation/Pipeline/BucketScriptAggregationTest.php new file mode 100644 index 0000000000000000000000000000000000000000..5dd8a05aa20f2f81696a978f19a7550350c39400 --- /dev/null +++ b/tests/Aggregation/Pipeline/BucketScriptAggregationTest.php @@ -0,0 +1,63 @@ +<?php + +/* + * This file is part of the ONGR package. + * + * (c) NFQ Technologies UAB <info@nfq.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace ONGR\ElasticsearchDSL\Tests\Aggregation\Pipeline; + +use ONGR\ElasticsearchDSL\Aggregation\Pipeline\BucketScriptAggregation; + +/** + * Unit test for bucket script pipeline aggregation. + */ +class BucketScriptAggregationTest extends \PHPUnit_Framework_TestCase +{ + /** + * Tests toArray method. + */ + public function testToArray() + { + $aggregation = new BucketScriptAggregation( + 'test', + [ + 'my_var1' => 'foo', + 'my_var2' => 'bar', + ] + ); + $aggregation->setScript('test script'); + $aggregation->addParameter('gap_policy', 'insert_zeros'); + + $expected = [ + 'bucket_script' => [ + 'buckets_path' => [ + 'my_var1' => 'foo', + 'my_var2' => 'bar', + ], + 'script' => 'test script', + 'gap_policy' => 'insert_zeros', + ], + ]; + + $this->assertEquals($expected, $aggregation->toArray()); + } + + /** + * Tests if the exception is thrown in getArray method if no + * buckets_path or script is set + * + * @expectedException \LogicException + * @expectedExceptionMessage `test` aggregation must have script set. + */ + public function testGetArrayException() + { + $agg = new BucketScriptAggregation('test', []); + + $agg->getArray(); + } +} diff --git a/tests/Aggregation/Pipeline/BucketSelectorAggregationTest.php b/tests/Aggregation/Pipeline/BucketSelectorAggregationTest.php new file mode 100644 index 0000000000000000000000000000000000000000..559c2d9b1cebde33d39c59dd39fae96c9416f23b --- /dev/null +++ b/tests/Aggregation/Pipeline/BucketSelectorAggregationTest.php @@ -0,0 +1,61 @@ +<?php + +/* + * This file is part of the ONGR package. + * + * (c) NFQ Technologies UAB <info@nfq.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace ONGR\ElasticsearchDSL\Tests\Aggregation\Pipeline; + +use ONGR\ElasticsearchDSL\Aggregation\Pipeline\BucketSelectorAggregation; + +/** + * Unit test for bucket selector pipeline aggregation. + */ +class BucketSelectorAggregationTest extends \PHPUnit_Framework_TestCase +{ + /** + * Tests toArray method. + */ + public function testToArray() + { + $aggregation = new BucketSelectorAggregation( + 'test', + [ + 'my_var1' => 'foo', + 'my_var2' => 'bar', + ] + ); + $aggregation->setScript('foo > bar'); + + $expected = [ + 'bucket_selector' => [ + 'buckets_path' => [ + 'my_var1' => 'foo', + 'my_var2' => 'bar', + ], + 'script' => 'foo > bar', + ], + ]; + + $this->assertEquals($expected, $aggregation->toArray()); + } + + /** + * Tests if the exception is thrown in getArray method if no + * buckets_path or script is set + * + * @expectedException \LogicException + * @expectedExceptionMessage `test` aggregation must have script set. + */ + public function testGetArrayException() + { + $agg = new BucketSelectorAggregation('test', []); + + $agg->getArray(); + } +}