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