Completed
Pull Request — master (#22)
by Sergey
12:24
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.125

Importance

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