Skip to content

Commit 223a25f

Browse files
authored
Add support for custom range key and refactor addRange in a trait (#2227)
IpRange and GeoDistance aggregations were missing the ability to specify a custom key for a range. As it was already done for the Range aggregation, I moved that to a trait that is now used everywhere we need `addRange`. For the IpRange aggregation, I also added the key option to the `addMaskRange` method. The only drawback with this refactoring is that the arguments of the trait have to allow string|int|float|null to be usable everywhere and we loose some phpdoc details on the arguments. In my opinion, people using this should already know what format is expected and can always check the doc so I personally prefer to have the code deduplicated, but if you disagree I can change it back to add the key everywhere without using a common trait.
1 parent e2cb89b commit 223a25f

File tree

7 files changed

+119
-97
lines changed

7 files changed

+119
-97
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1111
### Added
1212
* Added support for the multi-match query type `bool_prefix` [#2220](https://github.com/ruflin/Elastica/pull/2220)
1313
* Supported PHP 8.4 [#2221](https://github.com/ruflin/Elastica/pull/2221)
14+
* Added support for custom key to IpRange and GeoDistance `addRange` using a common trait [#2227](https://github.com/ruflin/Elastica/pull/2227)
1415

1516
### Changed
1617

src/Aggregation/GeoDistance.php

+1-31
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44

55
namespace Elastica\Aggregation;
66

7-
use Elastica\Exception\InvalidException;
8-
97
/**
108
* Class GeoDistance.
119
*
@@ -14,6 +12,7 @@
1412
class GeoDistance extends AbstractAggregation
1513
{
1614
use Traits\KeyedTrait;
15+
use Traits\RangeTrait;
1716

1817
public const DISTANCE_TYPE_ARC = 'arc';
1918
public const DISTANCE_TYPE_PLANE = 'plane';
@@ -56,35 +55,6 @@ public function setOrigin($origin): self
5655
return $this->setParam('origin', $origin);
5756
}
5857

59-
/**
60-
* Add a distance range to this aggregation.
61-
*
62-
* @param int|null $fromValue a distance
63-
* @param int|null $toValue a distance
64-
*
65-
* @throws InvalidException
66-
*
67-
* @return $this
68-
*/
69-
public function addRange(?int $fromValue = null, ?int $toValue = null): self
70-
{
71-
if (null === $fromValue && null === $toValue) {
72-
throw new InvalidException('Either fromValue or toValue must be set. Both cannot be null.');
73-
}
74-
75-
$range = [];
76-
77-
if (null !== $fromValue) {
78-
$range['from'] = $fromValue;
79-
}
80-
81-
if (null !== $toValue) {
82-
$range['to'] = $toValue;
83-
}
84-
85-
return $this->addParam('ranges', $range);
86-
}
87-
8858
/**
8959
* Set the unit of distance measure for this aggregation.
9060
*

src/Aggregation/IpRange.php

+8-30
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44

55
namespace Elastica\Aggregation;
66

7-
use Elastica\Exception\InvalidException;
8-
97
/**
108
* Class IpRange.
119
*
@@ -14,6 +12,7 @@
1412
class IpRange extends AbstractAggregation
1513
{
1614
use Traits\KeyedTrait;
15+
use Traits\RangeTrait;
1716

1817
/**
1918
* @param string $name the name of this aggregation
@@ -38,42 +37,21 @@ public function setField(string $field): self
3837
}
3938

4039
/**
41-
* Add an ip range to this aggregation.
42-
*
43-
* @param string|null $fromValue a valid ipv4 address. Low end of this range, exclusive (greater than)
44-
* @param string|null $toValue a valid ipv4 address. High end of this range, exclusive (less than)
40+
* Add an ip range in the form of a CIDR mask.
4541
*
46-
* @throws InvalidException
42+
* @param string $mask a valid CIDR mask
43+
* @param string|null $key customized key value
4744
*
4845
* @return $this
4946
*/
50-
public function addRange(?string $fromValue = null, ?string $toValue = null): self
47+
public function addMaskRange(string $mask, ?string $key = null): self
5148
{
52-
if (null === $fromValue && null === $toValue) {
53-
throw new InvalidException('Either fromValue or toValue must be set. Both cannot be null.');
54-
}
49+
$range = ['mask' => $mask];
5550

56-
$range = [];
57-
if (null !== $fromValue) {
58-
$range['from'] = $fromValue;
59-
}
60-
61-
if (null !== $toValue) {
62-
$range['to'] = $toValue;
51+
if (null !== $key) {
52+
$range['key'] = $key;
6353
}
6454

6555
return $this->addParam('ranges', $range);
6656
}
67-
68-
/**
69-
* Add an ip range in the form of a CIDR mask.
70-
*
71-
* @param string $mask a valid CIDR mask
72-
*
73-
* @return $this
74-
*/
75-
public function addMaskRange(string $mask): self
76-
{
77-
return $this->addParam('ranges', ['mask' => $mask]);
78-
}
7957
}

src/Aggregation/Range.php

+1-36
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44

55
namespace Elastica\Aggregation;
66

7-
use Elastica\Exception\InvalidException;
8-
97
/**
108
* Class Range.
119
*
@@ -14,38 +12,5 @@
1412
class Range extends AbstractSimpleAggregation
1513
{
1614
use Traits\KeyedTrait;
17-
18-
/**
19-
* Add a range to this aggregation.
20-
*
21-
* @param float|int|string|null $fromValue low end of this range, exclusive (greater than or equal to)
22-
* @param float|int|string|null $toValue high end of this range, exclusive (less than)
23-
* @param string|null $key customized key value
24-
*
25-
* @throws InvalidException
26-
*
27-
* @return $this
28-
*/
29-
public function addRange($fromValue = null, $toValue = null, ?string $key = null): self
30-
{
31-
if (null === $fromValue && null === $toValue) {
32-
throw new InvalidException('Either fromValue or toValue must be set. Both cannot be null.');
33-
}
34-
35-
$range = [];
36-
37-
if (null !== $fromValue) {
38-
$range['from'] = $fromValue;
39-
}
40-
41-
if (null !== $toValue) {
42-
$range['to'] = $toValue;
43-
}
44-
45-
if (null !== $key) {
46-
$range['key'] = $key;
47-
}
48-
49-
return $this->addParam('ranges', $range);
50-
}
15+
use Traits\RangeTrait;
5116
}

src/Aggregation/Traits/RangeTrait.php

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Elastica\Aggregation\Traits;
6+
7+
use Elastica\Exception\InvalidException;
8+
9+
trait RangeTrait
10+
{
11+
/**
12+
* Add a range to this aggregation.
13+
*
14+
* @param float|int|string|null $fromValue low end of this range, exclusive (greater than or equal to)
15+
* @param float|int|string|null $toValue high end of this range, exclusive (less than)
16+
* @param string|null $key customized key value
17+
*
18+
* @throws InvalidException
19+
*
20+
* @return $this
21+
*/
22+
public function addRange($fromValue = null, $toValue = null, ?string $key = null): self
23+
{
24+
if (null === $fromValue && null === $toValue) {
25+
throw new InvalidException('Either fromValue or toValue must be set. Both cannot be null.');
26+
}
27+
28+
$range = [];
29+
30+
if (null !== $fromValue) {
31+
$range['from'] = $fromValue;
32+
}
33+
34+
if (null !== $toValue) {
35+
$range['to'] = $toValue;
36+
}
37+
38+
if (null !== $key) {
39+
$range['key'] = $key;
40+
}
41+
42+
return $this->addParam('ranges', $range);
43+
}
44+
}

tests/Aggregation/GeoDistanceTest.php

+31
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,37 @@ public function testGeoDistanceKeyedAggregation(): void
5151
$this->assertSame($expected, \array_keys($results['buckets']));
5252
}
5353

54+
/**
55+
* @group unit
56+
*/
57+
public function testGeoDistanceAggregationWithKey(): void
58+
{
59+
$agg = new GeoDistance('geo', 'location', ['lat' => 32.804654, 'lon' => -117.242594]);
60+
$agg->addRange(null, 10, 'first');
61+
$agg->addRange(10, null, 'second');
62+
$agg->setUnit('mi');
63+
64+
$expected = [
65+
'geo_distance' => [
66+
'field' => 'location',
67+
'origin' => ['lat' => 32.804654, 'lon' => -117.242594],
68+
'unit' => 'mi',
69+
'ranges' => [
70+
[
71+
'to' => 10,
72+
'key' => 'first',
73+
],
74+
[
75+
'from' => 10,
76+
'key' => 'second',
77+
],
78+
],
79+
],
80+
];
81+
82+
$this->assertEquals($expected, $agg->toArray());
83+
}
84+
5485
protected function _getIndexForTest(): Index
5586
{
5687
$index = $this->_createIndex();

tests/Aggregation/IpRangeTest.php

+33
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,39 @@ public function testIpRangeKeyedAggregation(): void
6767
$this->assertSame($expected, \array_keys($results['buckets']));
6868
}
6969

70+
/**
71+
* @group unit
72+
*/
73+
public function testIpRangeAggregationWithKey(): void
74+
{
75+
$agg = new IpRange('ip', 'address');
76+
$agg->addRange('192.168.1.101', null, 'first');
77+
$agg->addRange(null, '192.168.1.200', 'second');
78+
$agg->addMaskRange('192.168.1.0/24', 'mask');
79+
80+
$expected = [
81+
'ip_range' => [
82+
'field' => 'address',
83+
'ranges' => [
84+
[
85+
'from' => '192.168.1.101',
86+
'key' => 'first',
87+
],
88+
[
89+
'to' => '192.168.1.200',
90+
'key' => 'second',
91+
],
92+
[
93+
'mask' => '192.168.1.0/24',
94+
'key' => 'mask',
95+
],
96+
],
97+
],
98+
];
99+
100+
$this->assertEquals($expected, $agg->toArray());
101+
}
102+
70103
protected function _getIndexForTest(): Index
71104
{
72105
$index = $this->_createIndex();

0 commit comments

Comments
 (0)