1
|
|
|
<?php namespace Nord\Lumen\Elasticsearch\Search\Scoring\Functions; |
2
|
|
|
|
3
|
|
|
use Nord\Lumen\Elasticsearch\Exceptions\InvalidArgument; |
4
|
|
|
use Nord\Lumen\Elasticsearch\Search\Traits\HasField; |
5
|
|
|
|
6
|
|
|
/** |
7
|
|
|
* Decay functions score a document with a function that decays depending on the distance of a numeric field value of |
8
|
|
|
* the document from a user given origin. This is similar to a range query, but with smooth edges instead of boxes. |
9
|
|
|
* |
10
|
|
|
* @see https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-function-score-query.html#function-decay |
11
|
|
|
*/ |
12
|
|
|
class DecayScoringFunction extends AbstractScoringFunction |
13
|
|
|
{ |
14
|
|
|
use HasField; |
15
|
|
|
|
16
|
|
|
const DECAY_FUNCTION_LINEAR = 'linear'; |
17
|
|
|
const DECAY_FUNCTION_EXPONENTIAL = 'exp'; |
18
|
|
|
const DECAY_FUNCTION_GAUSSIAN = 'gauss'; |
19
|
|
|
|
20
|
|
|
/** |
21
|
|
|
* @var string One of the `DECAY_FUNCTION_` constants. |
22
|
|
|
*/ |
23
|
|
|
private $decayFunction; |
24
|
|
|
|
25
|
|
|
/** |
26
|
|
|
* @var mixed The point of origin used for calculating distance. Must be given as a number for numeric field, date |
27
|
|
|
* for date fields and geo point for geo fields. Required for geo and numeric field. For date fields the default is |
28
|
|
|
* now. Date math (for example now-1h) is supported for origin. |
29
|
|
|
*/ |
30
|
|
|
private $origin; |
31
|
|
|
|
32
|
|
|
/** |
33
|
|
|
* @var mixed Required for all types. Defines the distance from origin at which the computed score will equal decay |
34
|
|
|
* parameter. For geo fields: Can be defined as number+unit (1km, 12m,…). Default unit is meters. For date fields: |
35
|
|
|
* Can to be defined as a number+unit ("1h", "10d",…). Default unit is milliseconds. For numeric field: Any number. |
36
|
|
|
*/ |
37
|
|
|
private $scale; |
38
|
|
|
|
39
|
|
|
/** |
40
|
|
|
* @var mixed If an offset is defined, the decay function will only compute the decay function for documents with a |
41
|
|
|
* distance greater that the defined offset. The default is 0. |
42
|
|
|
*/ |
43
|
|
|
private $offset; |
44
|
|
|
|
45
|
|
|
/** |
46
|
|
|
* @var mixed The decay parameter defines how documents are scored at the distance given at scale. If no decay is |
47
|
|
|
* defined, documents at the distance scale will be scored 0.5. |
48
|
|
|
*/ |
49
|
|
|
private $decay; |
50
|
|
|
|
51
|
|
|
|
52
|
|
|
/** |
53
|
|
|
* @inheritdoc |
54
|
|
|
*/ |
55
|
|
|
public function toArray() |
56
|
|
|
{ |
57
|
|
|
$options = [ |
58
|
|
|
'origin' => $this->getOrigin(), |
59
|
|
|
'scale' => $this->getScale(), |
60
|
|
|
]; |
61
|
|
|
$offset = $this->getOffset(); |
62
|
|
|
if (!empty($offset)) { |
63
|
|
|
$options['offset'] = $offset; |
64
|
|
|
} |
65
|
|
|
$decay = $this->getDecay(); |
66
|
|
|
if (!empty($decay)) { |
67
|
|
|
$options['decay'] = $decay; |
68
|
|
|
} |
69
|
|
|
|
70
|
|
|
return [ |
71
|
|
|
$this->getDecayFunction() => [ |
72
|
|
|
$this->getField() => $options |
73
|
|
|
], |
74
|
|
|
]; |
75
|
|
|
} |
76
|
|
|
|
77
|
|
|
|
78
|
|
|
/** |
79
|
|
|
* @return string |
80
|
|
|
*/ |
81
|
|
|
public function getDecayFunction() |
82
|
|
|
{ |
83
|
|
|
return $this->decayFunction; |
84
|
|
|
} |
85
|
|
|
|
86
|
|
|
|
87
|
|
|
/** |
88
|
|
|
* @param string $decayFunction |
89
|
|
|
* @return DecayScoringFunction |
90
|
|
|
*/ |
91
|
|
|
public function setDecayFunction($decayFunction) |
92
|
|
|
{ |
93
|
|
|
$this->assertDecayFunction($decayFunction); |
94
|
|
|
$this->decayFunction = $decayFunction; |
95
|
|
|
return $this; |
96
|
|
|
} |
97
|
|
|
|
98
|
|
|
|
99
|
|
|
/** |
100
|
|
|
* @return mixed |
101
|
|
|
*/ |
102
|
|
|
public function getOrigin() |
103
|
|
|
{ |
104
|
|
|
return $this->origin; |
105
|
|
|
} |
106
|
|
|
|
107
|
|
|
|
108
|
|
|
/** |
109
|
|
|
* @param mixed $origin |
110
|
|
|
* @return DecayScoringFunction |
111
|
|
|
*/ |
112
|
|
|
public function setOrigin($origin) |
113
|
|
|
{ |
114
|
|
|
$this->origin = $origin; |
115
|
|
|
return $this; |
116
|
|
|
} |
117
|
|
|
|
118
|
|
|
|
119
|
|
|
/** |
120
|
|
|
* @return mixed |
121
|
|
|
*/ |
122
|
|
|
public function getScale() |
123
|
|
|
{ |
124
|
|
|
return $this->scale; |
125
|
|
|
} |
126
|
|
|
|
127
|
|
|
|
128
|
|
|
/** |
129
|
|
|
* @param mixed $scale |
130
|
|
|
* @return DecayScoringFunction |
131
|
|
|
*/ |
132
|
|
|
public function setScale($scale) |
133
|
|
|
{ |
134
|
|
|
$this->scale = $scale; |
135
|
|
|
return $this; |
136
|
|
|
} |
137
|
|
|
|
138
|
|
|
|
139
|
|
|
/** |
140
|
|
|
* @return mixed |
141
|
|
|
*/ |
142
|
|
|
public function getOffset() |
143
|
|
|
{ |
144
|
|
|
return $this->offset; |
145
|
|
|
} |
146
|
|
|
|
147
|
|
|
|
148
|
|
|
/** |
149
|
|
|
* @param mixed $offset |
150
|
|
|
* @return DecayScoringFunction |
151
|
|
|
*/ |
152
|
|
|
public function setOffset($offset) |
153
|
|
|
{ |
154
|
|
|
$this->offset = $offset; |
155
|
|
|
return $this; |
156
|
|
|
} |
157
|
|
|
|
158
|
|
|
|
159
|
|
|
/** |
160
|
|
|
* @return mixed |
161
|
|
|
*/ |
162
|
|
|
public function getDecay() |
163
|
|
|
{ |
164
|
|
|
return $this->decay; |
165
|
|
|
} |
166
|
|
|
|
167
|
|
|
|
168
|
|
|
/** |
169
|
|
|
* @param mixed $decay |
170
|
|
|
* @return DecayScoringFunction |
171
|
|
|
*/ |
172
|
|
|
public function setDecay($decay) |
173
|
|
|
{ |
174
|
|
|
$this->decay = $decay; |
175
|
|
|
return $this; |
176
|
|
|
} |
177
|
|
|
|
178
|
|
|
|
179
|
|
|
/** |
180
|
|
|
* @param string $decayFunction |
181
|
|
|
* @throws InvalidArgument |
182
|
|
|
*/ |
183
|
|
View Code Duplication |
protected function assertDecayFunction($decayFunction) |
|
|
|
|
184
|
|
|
{ |
185
|
|
|
$validFunctions = [ |
186
|
|
|
self::DECAY_FUNCTION_LINEAR, |
187
|
|
|
self::DECAY_FUNCTION_EXPONENTIAL, |
188
|
|
|
self::DECAY_FUNCTION_GAUSSIAN, |
189
|
|
|
]; |
190
|
|
|
if (!in_array($decayFunction, $validFunctions)) { |
191
|
|
|
throw new InvalidArgument(sprintf( |
192
|
|
|
'DecayScoringFunction `decay_function` must be one of "%s", "%s" given.', |
193
|
|
|
implode(', ', $validFunctions), |
194
|
|
|
$decayFunction |
195
|
|
|
)); |
196
|
|
|
} |
197
|
|
|
} |
198
|
|
|
} |
199
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.