1<?php 2 3namespace Elastica\Aggregation; 4 5use Elastica\Exception\InvalidException; 6 7/** 8 * Class GeoDistance. 9 * 10 * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-geodistance-aggregation.html 11 */ 12class GeoDistance extends AbstractAggregation 13{ 14 use Traits\KeyedTrait; 15 16 public const DISTANCE_TYPE_ARC = 'arc'; 17 public const DISTANCE_TYPE_PLANE = 'plane'; 18 19 public const DEFAULT_DISTANCE_TYPE_VALUE = self::DISTANCE_TYPE_ARC; 20 public const DEFAULT_UNIT_VALUE = 'm'; 21 22 /** 23 * @param string $name the name if this aggregation 24 * @param string $field the field on which to perform this aggregation 25 * @param array|string $origin the point from which distances will be calculated 26 */ 27 public function __construct(string $name, string $field, $origin) 28 { 29 parent::__construct($name); 30 $this->setField($field)->setOrigin($origin); 31 } 32 33 /** 34 * Set the field for this aggregation. 35 * 36 * @param string $field the name of the document field on which to perform this aggregation 37 * 38 * @return $this 39 */ 40 public function setField(string $field): self 41 { 42 return $this->setParam('field', $field); 43 } 44 45 /** 46 * Set the origin point from which distances will be calculated. 47 * 48 * @param array|string $origin valid formats are array("lat" => 52.3760, "lon" => 4.894), "52.3760, 4.894", and array(4.894, 52.3760) 49 * 50 * @return $this 51 */ 52 public function setOrigin($origin): self 53 { 54 return $this->setParam('origin', $origin); 55 } 56 57 /** 58 * Add a distance range to this aggregation. 59 * 60 * @param int|null $fromValue a distance 61 * @param int|null $toValue a distance 62 * 63 * @throws InvalidException 64 * 65 * @return $this 66 */ 67 public function addRange(?int $fromValue = null, ?int $toValue = null): self 68 { 69 if (null === $fromValue && null === $toValue) { 70 throw new InvalidException('Either fromValue or toValue must be set. Both cannot be null.'); 71 } 72 73 $range = []; 74 75 if (null !== $fromValue) { 76 $range['from'] = $fromValue; 77 } 78 79 if (null !== $toValue) { 80 $range['to'] = $toValue; 81 } 82 83 return $this->addParam('ranges', $range); 84 } 85 86 /** 87 * Set the unit of distance measure for this aggregation. 88 * 89 * @param string $unit defaults to m 90 * 91 * @return $this 92 */ 93 public function setUnit(string $unit): self 94 { 95 return $this->setParam('unit', $unit); 96 } 97 98 /** 99 * Set the method by which distances will be calculated. 100 * 101 * @param string $distanceType see DISTANCE_TYPE_* constants for options. Defaults to arc. 102 * 103 * @return $this 104 */ 105 public function setDistanceType(string $distanceType): self 106 { 107 return $this->setParam('distance_type', $distanceType); 108 } 109} 110