Passed
Pull Request — develop (#25)
by Sam
07:16 queued 02:23
created

MatchQuery::getField()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php namespace Nord\Lumen\Elasticsearch\Search\Query\FullText;
2
3
use Nord\Lumen\Elasticsearch\Exceptions\InvalidArgument;
4
use Nord\Lumen\Elasticsearch\Search\Query\Traits\HasField;
5
use Nord\Lumen\Elasticsearch\Search\Query\Traits\HasType;
6
use Nord\Lumen\Elasticsearch\Search\Query\Traits\HasValue;
7
8
/**
9
 * A family of match queries that accepts text/numerics/dates, analyzes them, and constructs a query.
10
 *
11
 * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-match-query.html
12
 */
13
class MatchQuery extends AbstractQuery
14
{
15
    use HasField;
16
    use HasType;
17
    use HasValue;
18
    
19
    const OPERATOR_OR = 'or';
20
    const OPERATOR_AND = 'and';
21
22
    const ZERO_TERM_QUERY_NONE = 'none';
23
    const ZERO_TERM_QUERY_ALL = 'all';
24
25
    const TYPE_PHRASE = 'phrase';
26
    const TYPE_PHRASE_PREFIX = 'phrase_prefix';
27
28
    /**
29
     * @var string The operator flag can be set to "or" or "and" to control the boolean clauses (defaults to "or").
30
     */
31
    private $operator;
32
33
    /**
34
     * @var string If the analyzer used removes all tokens in a query like a "stop" filter does, the default behavior
35
     * is to match no documents at all. In order to change that the zero_terms_query option can be used, which accepts
36
     * "none" (default) and "all" which corresponds to a "match_all" query.
37
     */
38
    private $zeroTermsQuery;
39
40
    /**
41
     * @var float The match query supports a cutoff_frequency that allows specifying an absolute or relative document
42
     * frequency where high frequency terms are moved into an optional subquery and are only scored if one of the low
43
     * frequency (below the cutoff) terms in the case of an or operator or all of the low frequency terms in the case
44
     * of an and operator match.
45
     */
46
    private $cutOffFrequency;
47
48
    /**
49
     * @var int A phrase query matches terms up to a configurable slop (which defaults to 0) in any order.
50
     * Transposed terms have a slop of 2.
51
     */
52
    private $slop;
53
54
    /**
55
     * @var int A "phrase_prefix" query option that controls to how many prefixes the last term will be expanded.
56
     * It is highly recommended to set it to an acceptable value to control the execution time of the query.
57
     */
58
    private $maxExpansions;
59
60
    /**
61
     * @var string The analyzer can be set to control which analyzer will perform the analysis process on the text. It
62
     * defaults to the field explicit mapping definition, or the default search analyzer,
63
     */
64
    private $analyzer;
65
66
    /**
67
     * @inheritdoc
68
     */
69
    public function toArray()
70
    {
71
        $match = ['query' => $this->getValue()];
72
73
        $match = $this->applyOptions($match);
74
75
        if (count($match) === 1 && isset($match['query'])) {
76
            $match = $match['query'];
77
        }
78
79
        return ['match' => [$this->getField() => $match]];
80
    }
81
82
83
    /**
84
     * @param string $operator
85
     * @return MatchQuery
86
     * @throws InvalidArgument
87
     */
88
    public function setOperator($operator)
89
    {
90
        $this->assertOperator($operator);
91
        $this->operator = $operator;
92
        return $this;
93
    }
94
95
96
    /**
97
     * @return string
98
     */
99
    public function getOperator()
100
    {
101
        return $this->operator;
102
    }
103
104
105
    /**
106
     * @param string $zeroTermsQuery
107
     * @return MatchQuery
108
     * @throws InvalidArgument
109
     */
110
    public function setZeroTermsQuery($zeroTermsQuery)
111
    {
112
        $this->assertZeroTermsQuery($zeroTermsQuery);
113
        $this->zeroTermsQuery = $zeroTermsQuery;
114
        return $this;
115
    }
116
117
118
    /**
119
     * @return string
120
     */
121
    public function getZeroTermsQuery()
122
    {
123
        return $this->zeroTermsQuery;
124
    }
125
126
127
    /**
128
     * @param float $cutOffFrequency
129
     * @return MatchQuery
130
     * @throws InvalidArgument
131
     */
132
    public function setCutOffFrequency($cutOffFrequency)
133
    {
134
        $this->assertCutOffFrequency($cutOffFrequency);
135
        $this->cutOffFrequency = $cutOffFrequency;
136
        return $this;
137
    }
138
139
140
    /**
141
     * @return float
142
     */
143
    public function getCutOffFrequency()
144
    {
145
        return $this->cutOffFrequency;
146
    }
147
148
149
    /**
150
     * @param string $type
151
     * @return MatchQuery
152
     * @throws InvalidArgument
153
     */
154
    public function setType($type)
155
    {
156
        $this->assertType($type);
157
        $this->type = $type;
158
        return $this;
159
    }
160
161
162
    /**
163
     * @param int $slop
164
     * @return MatchQuery
165
     * @throws InvalidArgument
166
     */
167
    public function setSlop($slop)
168
    {
169
        $this->assertSlop($slop);
170
        $this->slop = $slop;
171
        return $this;
172
    }
173
174
175
    /**
176
     * @return int
177
     */
178
    public function getSlop()
179
    {
180
        return $this->slop;
181
    }
182
183
184
    /**
185
     * @param int $maxExpansions
186
     * @return MatchQuery
187
     * @throws InvalidArgument
188
     */
189
    public function setMaxExpansions($maxExpansions)
190
    {
191
        $this->assertMaxExpansions($maxExpansions);
192
        $this->maxExpansions = $maxExpansions;
193
        return $this;
194
    }
195
196
197
    /**
198
     * @return int
199
     */
200
    public function getMaxExpansions()
201
    {
202
        return $this->maxExpansions;
203
    }
204
205
206
    /**
207
     * @param string $analyzer
208
     * @return MatchQuery
209
     */
210
    public function setAnalyzer($analyzer)
211
    {
212
        $this->analyzer = $analyzer;
213
        return $this;
214
    }
215
216
217
    /**
218
     * @return string
219
     */
220
    public function getAnalyzer()
221
    {
222
        return $this->analyzer;
223
    }
224
225
226
    /**
227
     * @param array $match
228
     * @return array
229
     */
230
    protected function applyOptions(array $match)
231
    {
232
        $operator = $this->getOperator();
233
        if (!is_null($operator)) {
234
            $match['operator'] = $operator;
235
        }
236
        $zeroTermsQuery = $this->getZeroTermsQuery();
237
        if (!is_null($zeroTermsQuery)) {
238
            $match['zero_terms_query'] = $zeroTermsQuery;
239
        }
240
        $cutOffFreq = $this->getCutOffFrequency();
241
        if (!is_null($cutOffFreq)) {
242
            $match['cutoff_frequency'] = $cutOffFreq;
243
        }
244
        $type = $this->getType();
245
        if (!is_null($type)) {
246
            $match['type'] = $type;
247
            $slop = $this->getSlop();
248
            if (!is_null($slop)) {
249
                $match['slop'] = $slop;
250
            }
251
            if ($match['type'] === self::TYPE_PHRASE_PREFIX) {
252
                $maxExp = $this->getMaxExpansions();
253
                if (!is_null($maxExp)) {
254
                    $match['max_expansions'] = $maxExp;
255
                }
256
            }
257
        }
258
        $analyzer = $this->getAnalyzer();
259
        if (!is_null($analyzer)) {
260
            $match['analyzer'] = $analyzer;
261
        }
262
263
        return $match;
264
    }
265
266
267
    /**
268
     * @param string $operator
269
     * @throws InvalidArgument
270
     */
271 View Code Duplication
    protected function assertOperator($operator)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
272
    {
273
        $validOperators = [self::OPERATOR_AND, self::OPERATOR_OR];
274
        if (!in_array($operator, $validOperators)) {
275
            throw new InvalidArgument(sprintf(
276
                'Match Query `operator` must be one of "%s", "%s" given.',
277
                implode(', ', $validOperators),
278
                $operator
279
            ));
280
        }
281
    }
282
283
284
    /**
285
     * @param string $zeroTermsQuery
286
     * @throws InvalidArgument
287
     */
288 View Code Duplication
    protected function assertZeroTermsQuery($zeroTermsQuery)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
289
    {
290
        $validZeroTermQueries = [self::ZERO_TERM_QUERY_NONE, self::ZERO_TERM_QUERY_ALL];
291
        if (!in_array($zeroTermsQuery, $validZeroTermQueries)) {
292
            throw new InvalidArgument(sprintf(
293
                'Match Query `zero_terms_query` must be one of "%s", "%s" given.',
294
                implode(', ', $validZeroTermQueries),
295
                $zeroTermsQuery
296
            ));
297
        }
298
    }
299
300
301
    /**
302
     * @param float $cutOffFrequency
303
     * @throws InvalidArgument
304
     */
305
    protected function assertCutOffFrequency($cutOffFrequency)
306
    {
307
        if (!is_float($cutOffFrequency)) {
308
            throw new InvalidArgument(sprintf(
309
                'Match Query `cutoff_frequency` must be a float value, "%s" given.',
310
                gettype($cutOffFrequency)
311
            ));
312
        }
313
    }
314
315
316
    /**
317
     * @param string $type
318
     * @throws InvalidArgument
319
     */
320 View Code Duplication
    protected function assertType($type)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
321
    {
322
        $validTypes = [self::TYPE_PHRASE, self::TYPE_PHRASE_PREFIX];
323
        if (!in_array($type, $validTypes)) {
324
            throw new InvalidArgument(sprintf(
325
                'Match Query `type` must be one of "%s", "%s" given.',
326
                implode(', ', $validTypes),
327
                $type
328
            ));
329
        }
330
    }
331
332
333
    /**
334
     * @param int $slop
335
     * @throws InvalidArgument
336
     */
337
    protected function assertSlop($slop)
338
    {
339
        if (!is_int($slop)) {
340
            throw new InvalidArgument(sprintf(
341
                'Match Query `slop` must be an integer, "%s" given.',
342
                gettype($slop)
343
            ));
344
        }
345
    }
346
347
348
    /**
349
     * @param int $maxExpansions
350
     * @throws InvalidArgument
351
     */
352
    protected function assertMaxExpansions($maxExpansions)
353
    {
354
        if (!is_int($maxExpansions)) {
355
            throw new InvalidArgument(sprintf(
356
                'Match Query `max_expansions` must be an integer, "%s" given.',
357
                gettype($maxExpansions)
358
            ));
359
        }
360
    }
361
}
362