forked from ruflin/Elastica
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Backport Weighted average aggregation in 6.x (ruflin#1773)
This is a backport of ruflin#1771 in branch 6.x
- Loading branch information
1 parent
5a93853
commit 19e8615
Showing
3 changed files
with
209 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
<?php | ||
|
||
namespace Elastica\Aggregation; | ||
|
||
use Elastica\Exception\InvalidException; | ||
|
||
/** | ||
* Class WeightedAvg. | ||
* | ||
* @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-weight-avg-aggregation.html | ||
*/ | ||
class WeightedAvg extends AbstractAggregation | ||
{ | ||
/** | ||
* Set the value for this aggregation. | ||
* | ||
* @param mixed $missing | ||
* | ||
* @return $this | ||
*/ | ||
public function setValue(string $field, $missing = null) | ||
{ | ||
if ($this->hasParam('value') && isset($this->getParam('value')['script'])) { | ||
throw new InvalidException('Weighted Average aggregation with a value mixing field and script is not possible.'); | ||
} | ||
|
||
$value = ['field' => $field]; | ||
|
||
if (null !== $missing) { | ||
$value['missing'] = $missing; | ||
} | ||
|
||
return $this->setParam('value', $value); | ||
} | ||
|
||
/** | ||
* Set the value as a script for this aggregation. | ||
* | ||
* @return $this | ||
*/ | ||
public function setValueScript(string $script) | ||
{ | ||
if ($this->hasParam('value') && isset($this->getParam('value')['field'])) { | ||
throw new InvalidException('Weighted Average aggregation with a value mixing field and script is not possible.'); | ||
} | ||
|
||
return $this->setParam('value', ['script' => $script]); | ||
} | ||
|
||
/** | ||
* Set the weight for this aggregation. | ||
* | ||
* @param mixed $missing | ||
* | ||
* @return $this | ||
*/ | ||
public function setWeight(string $field, $missing = null) | ||
{ | ||
if ($this->hasParam('weight') && isset($this->getParam('weight')['script'])) { | ||
throw new InvalidException('Weighted Average aggregation with a weight mixing field and script is not possible.'); | ||
} | ||
|
||
$weight = ['field' => $field]; | ||
|
||
if (null !== $missing) { | ||
$weight['missing'] = $missing; | ||
} | ||
|
||
return $this->setParam('weight', $weight); | ||
} | ||
|
||
/** | ||
* Set the weight as a script for this aggregation. | ||
* | ||
* @return $this | ||
*/ | ||
public function setWeightScript(string $script) | ||
{ | ||
if ($this->hasParam('weight') && isset($this->getParam('weight')['field'])) { | ||
throw new InvalidException('Weighted Average aggregation with a weight mixing field and script is not possible.'); | ||
} | ||
|
||
return $this->setParam('weight', ['script' => $script]); | ||
} | ||
|
||
/** | ||
* Set the format for this aggregation. | ||
* | ||
* @param string $format | ||
* | ||
* @return $this | ||
*/ | ||
public function setFormat($format) | ||
{ | ||
return $this->setParam('format', $format); | ||
} | ||
|
||
/** | ||
* Set the value_type for this aggregation. | ||
* | ||
* @param string $format | ||
* | ||
* @return $this | ||
*/ | ||
public function setValueType($valueType) | ||
{ | ||
return $this->setParam('value_type', $valueType); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
<?php | ||
|
||
namespace Elastica\Test\Aggregation; | ||
|
||
use Elastica\Aggregation\WeightedAvg; | ||
use Elastica\Document; | ||
use Elastica\Exception\InvalidException; | ||
use Elastica\Query; | ||
|
||
class WeightedAvgTest extends BaseAggregationTest | ||
{ | ||
protected function _getIndexForTest() | ||
{ | ||
$index = $this->_createIndex(); | ||
|
||
$index->getType('_doc')->addDocuments([ | ||
new Document(1, ['price' => 5, 'weight' => 3]), | ||
new Document(2, ['price' => 8, 'weight' => 1]), | ||
new Document(3, ['price' => 1, 'weight' => 1]), | ||
new Document(4, ['price' => 3]), | ||
]); | ||
|
||
$index->refresh(); | ||
|
||
return $index; | ||
} | ||
|
||
/** | ||
* @group functional | ||
*/ | ||
public function testWeightedAvgAggregation() | ||
{ | ||
$this->_checkVersion('6.4'); | ||
|
||
$agg = new WeightedAvg('weighted'); | ||
$agg->setValue('price'); | ||
$weightWhenMissing = 2; | ||
$agg->setWeight('weight', $weightWhenMissing); | ||
|
||
$query = new Query(); | ||
$query->addAggregation($agg); | ||
|
||
$resultSet = $this->_getIndexForTest()->search($query); | ||
$results = $resultSet->getAggregations(); | ||
|
||
$this->assertTrue($resultSet->hasAggregations()); | ||
$this->assertEquals((5 * 3 + 8 + 1 + 3 * $weightWhenMissing) / 7.0, $results['weighted']['value']); | ||
} | ||
|
||
/** | ||
* @group unit | ||
*/ | ||
public function testItsNotPossibleToMixValueFieldAndScript() | ||
{ | ||
$agg = new WeightedAvg('weighted'); | ||
$agg->setValue('price'); | ||
|
||
$this->expectExceptionObject(new InvalidException('Weighted Average aggregation with a value mixing field and script is not possible.')); | ||
$agg->setValueScript('doc.price.value + 1'); | ||
} | ||
|
||
/** | ||
* @group unit | ||
*/ | ||
public function testItsNotPossibleToMixValueScriptAndField() | ||
{ | ||
$agg = new WeightedAvg('weighted'); | ||
$agg->setValueScript('doc.price.value + 1'); | ||
|
||
$this->expectExceptionObject(new InvalidException('Weighted Average aggregation with a value mixing field and script is not possible.')); | ||
$agg->setValue('price'); | ||
} | ||
|
||
/** | ||
* @group unit | ||
*/ | ||
public function testItsNotPossibleToMixWeightFieldAndScript() | ||
{ | ||
$agg = new WeightedAvg('weighted'); | ||
$agg->setWeight('weight'); | ||
|
||
$this->expectExceptionObject(new InvalidException('Weighted Average aggregation with a weight mixing field and script is not possible.')); | ||
$agg->setWeightScript('doc.weight.value + 1'); | ||
} | ||
|
||
/** | ||
* @group unit | ||
*/ | ||
public function testItsNotPossibleToMixWeightScriptAndField() | ||
{ | ||
$agg = new WeightedAvg('weighted'); | ||
$agg->setWeightScript('doc.weight.value + 1'); | ||
|
||
$this->expectExceptionObject(new InvalidException('Weighted Average aggregation with a weight mixing field and script is not possible.')); | ||
$agg->setWeight('weight'); | ||
} | ||
} |