Completed
Pull Request — develop (#85)
by Sam
04:06 queued 01:52
created

MatchQuery::assertSlop()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

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