forked from elasticquent/Elasticquent
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Builder.php
390 lines (331 loc) · 10.1 KB
/
Builder.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
<?php namespace Elasticquent;
use Elastica\Query;
use Elastica\Query\Common;
use Elastica\Query\Fuzzy;
use Elastica\Query\FuzzyLikeThis;
use Elastica\Query\Match;
use Elastica\Query\MatchAll;
use Elastica\Query\MultiMatch;
use Elastica\Query\Range;
use Elastica\Query\Regexp;
use Elastica\Query\Term;
use Elastica\Query\Terms;
use Elastica\Query\Wildcard;
use Elastica\Query\AbstractQuery;
class Builder
{
/**
* An array of queries to be searched.
*
* @var array
*/
protected $query = [];
/**
* The results of the query.
*
* @var mixed
*/
protected $results;
/**
* Find all documents where the values are matched in the field. The type option
* allows you to specify the type of match, can be either phrase or phrase_prefix.
*
* The phrase match analyzes the text and creates a phrase query out of the
* analyzed text.
*
* The phrase prefix match is the same as phrase, except that it allows for
* prefix matches on the last term in the text.
*
* @link https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-match-query.html
*
* @param string $field The field to search in the index
* @param string $query The values to search for
* @param string $type The match type
* @param bool $fuzzy Set whether the match should be fuzzy
* @return Query
*/
public function match($field, $query, $type = 'phrase', $fuzzy = false)
{
$match = new Match();
$match->setFieldQuery($field, $query);
$match->setFieldType($field, $type);
if ($fuzzy) {
$match->setFieldFuzziness($field, 'AUTO');
}
$query = $this->newQuery($match);
$this->query[] = $query;
return $query;
}
/**
* Find all documents where the value is matched in the fields. The type option
* allows you to specify the type of match, can be best_fields, most_fields,
* cross_fields, phrase, phrase_prefix.
*
* best_fields finds documents which match any field, but uses the _score
* from the best field.
*
* most_fields finds documents which match any field and combines the _score
* from each field.
*
* cross_fields treats fields with the same analyzer as though they were
* one big field. Looks for each word in any field.
*
* phrase runs a match_phrase query on each field and combines the _score
* from each field.
*
* phrase_prefix runs a match_phrase_prefix query on each field and combines
* the _score from each field.
*
* @link https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-multi-match-query.html
*
* @param array $fields The fields to search in
* @param string $query The string to search for
* @param string $type The match type
* @param bool $fuzzy Set whether the match should be fuzzy
* @param float $tieBreaker Can be between 0.0 and 1.0
* @param string $operator Can be 'and' or 'or'
* @return Query
*/
public function multiMatch(
array $fields,
$query,
$type = 'phrase',
$fuzzy = false,
$tieBreaker = 0.0,
$operator = 'and'
) {
$match = new MultiMatch();
$match->setFields($fields);
$match->setQuery($query);
$match->setType($type);
if ($fuzzy) {
$match->setFuzziness('AUTO');
}
if ($type == 'best_fields') {
$match->setTieBreaker($tieBreaker);
}
if ($type == 'cross_fields') {
$match->setOperator($operator);
}
$query = $this->newQuery($match);
$this->query[] = $query;
return $query;
}
/**
* Finds all documents matching the query but groups common words,
* i.e. the, and runs them after the initial query for more efficiency.
*
* @link https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-common-terms-query.html
*
* @param string $field
* @param string $query
* @param float $cutOff
* @param int|bool $minimumMatch
* @return Query
*/
public function common($field, $query, $cutOff = 0.001, $minimumMatch = false)
{
$common = new Common($field, $query, $cutOff);
if ($minimumMatch) {
$common->setMinimumShouldMatch($minimumMatch);
}
$query = $this->newQuery($common);
$this->query[] = $query;
return $query;
}
/**
* A query which matches all documents.
*
* @return Query
*/
public function matchAll()
{
$match = new MatchAll();
$query = $this->newQuery($match);
$this->query[] = $query;
return $query;
}
/**
* Find all documents in a given range. The range is provided as an array with
* at least either a 'lt' or 'lte' key and a 'gt' or 'gte' key.
*
* 'lt' stands for less than
* 'lte' for less than or equal to
* 'gt' for greater than
* 'gte' for greater than or equal to
*
* @link https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-range-query.html
*
* @param string $field
* @param array $range
* @param bool $timeZone
* @param bool $format
* @return Query
*/
public function range($field, array $range, $timeZone = false, $format = false)
{
$range = new Range($field, $range);
if ($timeZone) {
$range->setParam('time_zone', $timeZone);
}
if ($format) {
$range->setParam('format', $format);
}
$query = $this->newQuery($range);
$this->query[] = $query;
return $query;
}
/**
* Find all documents matching the provided regular expression.
*
* @link https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-regexp-query.html
*
* @param string $field
* @param string $regex
* @return Query
*/
public function regexp($field, $regex)
{
$regexp = new Regexp($field, $regex);
$query = $this->newQuery($regexp);
$this->query[] = $query;
return $query;
}
/**
* Find a document matching an exact term.
*
* @link https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-term-query.html
*
* @param string $key
* @param string $value
* @param float $boost
* @return Query
*/
public function term($key, $value, $boost = 1.0)
{
$term = new Term();
$term->setTerm($key, $value, $boost);
$query = $this->newQuery($term);
$this->query[] = $query;
return $query;
}
/**
* Find any documents matching the provided terms, optionally you can set a
* minimum amount of terms to match.
*
* @param string $key
* @param array $terms
* @param bool|int $minimumShouldMatch
* @return Query
*/
public function terms($key, array $terms, $minimumShouldMatch = false)
{
$query = new Terms($key, $terms);
if ($minimumShouldMatch) {
$query->setMinimumMatch($minimumShouldMatch);
}
$query = $this->newQuery($query);
$this->query[] = $query;
return $query;
}
/**
* Find a document matching a value containing a wildcard. Please note wildcard
* queries can be very slow, to avoid this don't start a string with a wildcard.
*
* @link https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-wildcard-query.html
*
* @param string $key
* @param string $value
* @param float $boost
* @return Query
*/
public function wildcard($key, $value, $boost = 1.0)
{
$query = new Wildcard($key, $value, $boost);
$query = $this->newQuery($query);
$this->query[] = $query;
return $query;
}
/**
* The fuzzy query generates all possible matching terms that are within
* the maximum edit distance specified in fuzziness and then checks the
* term dictionary to find out which of those generated terms actually
* exist in the index.
*
* @link https://www.elastic.co/guide/en/elasticsearch/reference/1.4/query-dsl-fuzzy-query.html
*
* @param string $key
* @param string $value
* @param array $options
* @return Fuzzy
*/
public function fuzzy($key, $value, $options = [])
{
$query = new Fuzzy($key, $value);
foreach ($options as $option => $value) {
$query->setFieldOption($option, $value);
}
$this->query[] = $this->newQuery($query);
return $query;
}
/**
* Find documents that are "like" provided text by running it against one or more
* fields.
*
* @link https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-flt-query.html
*
* @param string $value
* @param array $fields
* @param float $fuzziness
* @return FuzzyLikeThis
*/
public function fuzzyLikeThis($value, array $fields = [], $fuzziness = 0.5)
{
$query = new FuzzyLikeThis();
$query->setLikeText($value);
if (!empty($fields)) {
$query->addFields($fields);
}
$query->setMinSimilarity($fuzziness);
$this->query[] = $this->newQuery($query);
return $query;
}
/**
* Add an abstract elastica query to array
*
* @param AbstractQuery $query
* @return Query
*/
public function addQuery(AbstractQuery $query)
{
$query = $this->newQuery($query);
$this->query[] = $query;
return $query;
}
/**
* Get the queries to be run.
*
* @return array
*/
public function getQuery()
{
return $this->query;
}
/**
* Create a new query wrapper.
*
* @param mixed $query
* @return Query
*/
protected function newQuery($query)
{
return new Query($query);
}
public function sortBy($sort)
{
$query = new \Elastica\Query('agg_name');
$query->setSort($sort);
$this->query[] = $query;
return $query;
}
}