Completed
Push — master ( 816340...ab4a72 )
by Sergey
05:20
created

QueryBuilder::getQuery()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
2
3
namespace Isswp101\Persimmon\QueryBuilder;
4
5
use Isswp101\Persimmon\QueryBuilder\Aggregations\Aggregation;
6
use Isswp101\Persimmon\QueryBuilder\Filters\Filter;
7
8
class QueryBuilder
9
{
10
    /**
11
     * Query.
12
     *
13
     * @var array
14
     */
15
    protected $query = [];
16
17
    /**
18
     * Constructor.
19
     *
20
     * @param array $body
21
     */
22 8
    public function __construct(array $body = [])
23
    {
24 8
        $this->query['body'] = $body;
25 8
    }
26
27
    /**
28
     * @param int $from
29
     * @return $this
30
     */
31
    public function from($from)
32
    {
33
        $this->query['from'] = $from;
34
        return $this;
35
    }
36
37
    /**
38
     * @param int $size
39
     * @return $this
40
     */
41 2
    public function size($size)
42
    {
43 2
        $this->query['size'] = $size;
44 2
        return $this;
45
    }
46
47
    /**
48
     * @return bool
49
     */
50
    public function hasSort()
51
    {
52
        return !empty($this->query['body']['sort']);
53
    }
54
55
    /**
56
     * @param array|string $sort
57
     * @return $this
58
     */
59
    public function sort($sort)
60
    {
61
        $this->query['body']['sort'] = $sort;
62
        return $this;
63
    }
64
65
    /**
66
     * @param Filter|array $filter
67
     * @param string $mode
68
     * @return $this
69
     */
70 6
    public function filter($filter = [], $mode = Filter::MODE_INCLUDE)
71
    {
72
        $map = [
73 6
            Filter::MODE_INCLUDE => 'must',
74 6
            Filter::MODE_EXCLUDE => 'must_not',
75
            'should' => 'should'
76 6
        ];
77
78 6
        $mode = $map[$mode];
79
80 6
        if (!$filter) {
81
            unset($this->query['body']['filter']);
82
            return $this;
83
        }
84
85 6
        if ($filter instanceof Filter) {
86 6
            $filter = $filter->makeQuery();
87 6
        }
88
89 6
        $this->merge($filter, $mode);
90
91 6
        return $this;
92
    }
93
94
    /**
95
     * Set _source to search query.
96
     *
97
     * @param mixed $fields
98
     * @return $this
99
     */
100
    public function fields($fields = false)
101
    {
102
        if ($fields === false) {
103
            $this->query['body']['_source'] = false;
104
        } elseif ((array)$fields == ['*']) {
105
            unset($this->query['body']['_source']);
106
        } else {
107
            $this->query['body']['_source'] = $fields;
108
        }
109
        return $this;
110
    }
111
112
    /**
113
     * Return only _id.
114
     *
115
     * @return $this
116
     */
117
    public function getOnlyIds()
118
    {
119
        return $this->fields(false);
120
    }
121
122
    /**
123
     * Return query.
124
     *
125
     * @return array
126
     */
127 8
    protected function getQuery()
128
    {
129 8
        return $this->query;
130
    }
131
132
    /**
133
     * Build query.
134
     *
135
     * @return array
136
     */
137 8
    public function build()
138
    {
139 8
        return $this->getQuery();
140
    }
141
142
    /**
143
     * @return string
144
     */
145
    public function __toString()
146
    {
147
        return $this->toJson();
148
    }
149
150
    /**
151
     * @param int $options
152
     * @return string
153
     */
154
    public function toJson($options = 0)
155
    {
156
        return json_encode($this->getQuery(), $options);
157
    }
158
159 6
    protected function merge(array $query, $mode = 'must')
160
    {
161 6
        if (!array_key_exists('filter', $this->query['body'])) {
162 6
            $this->query['body']['filter']['bool'][$mode] = [];
163 6
        }
164
165 6
        $this->query['body']['filter']['bool'][$mode][] = $query;
166
167 6
        return $this;
168
    }
169
170 2
    public function aggregation(Aggregation $aggregation)
171
    {
172 2
        $this->query['body']['aggs'][$aggregation->getName()] = $aggregation->make();
173 2
        return $this;
174
    }
175
176
    public function where($field, $value)
177
    {
178
        $query = ['term' => [$field => $value]];
179
        $this->merge($query);
180
        return $this;
181
    }
182
183
    public function notWhere($field, $value)
184
    {
185
        $query = ['term' => [$field => $value]];
186
        $this->merge($query, 'must_not');
187
        return $this;
188
    }
189
190
    public function orWhere($field, $value)
191
    {
192
        $query = ['term' => [$field => $value]];
193
        $this->merge($query, 'should');
194
        return $this;
195
    }
196
197
    public function between($field, $start, $end)
198
    {
199
        $query = ['range' => [$field => ['gt' => $start, 'lt' => $end]]];
200
        $this->merge($query);
201
        return $this;
202
    }
203
204
    public function betweenOrEquals($field, $start, $end)
205
    {
206
        $query = ['range' => [$field => ['gte' => $start, 'lte' => $end]]];
207
        $this->merge($query);
208
        return $this;
209
    }
210
211
    public function range($field, $start, $end)
212
    {
213
        return $this->betweenOrEquals($field, $start, $end);
214
    }
215
216
    public function greaterThan($field, $start)
217
    {
218
        $query = ['range' => [$field => ['gt' => $start]]];
219
        $this->merge($query);
220
        return $this;
221
    }
222
223
    public function gt($field, $start)
224
    {
225
        return $this->greaterThan($field, $start);
226
    }
227
228
    public function greaterThanOrEquals($field, $start)
229
    {
230
        $query = ['range' => [$field => ['gte' => $start]]];
231
        $this->merge($query);
232
        return $this;
233
    }
234
235
    public function gte($field, $start)
236
    {
237
        return $this->greaterThanOrEquals($field, $start);
238
    }
239
240
    public function lessThan($field, $end)
241
    {
242
        $query = ['range' => [$field => ['lt' => $end]]];
243
        $this->merge($query);
244
        return $this;
245
    }
246
247
    public function lt($field, $start)
248
    {
249
        return $this->lessThan($field, $start);
250
    }
251
252
    public function lessThanOrEquals($field, $end)
253
    {
254
        $query = ['range' => [$field => ['lte' => $end]]];
255
        $this->merge($query);
256
        return $this;
257
    }
258
259
    public function lte($field, $start)
260
    {
261
        return $this->lessThanOrEquals($field, $start);
262
    }
263
264
    public function match($field, $value)
265
    {
266
        $query = ['query' => ['match' => [$field => $value]]];
267
        $this->merge($query);
268
        return $this;
269
    }
270
271
    public function notMatch($field, $value)
272
    {
273
        $query = ['query' => ['match' => [$field => $value]]];
274
        $this->merge($query, 'must_not');
275
        return $this;
276
    }
277
278
    public function orMatch($field, $value)
279
    {
280
        $query = ['query' => ['match' => [$field => $value]]];
281
        $this->merge($query, 'should');
282
        return $this;
283
    }
284
}
285