Passed
Push — master ( 1d9ce7...5519f6 )
by Mehmet
02:57
created

ElasticSearch::get()   B

Complexity

Conditions 6
Paths 18

Size

Total Lines 40
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 1
Metric Value
c 2
b 0
f 1
dl 0
loc 40
rs 8.439
cc 6
eloc 28
nc 18
nop 2
1
<?php
2
3
namespace Soupmix;
4
/*
5
Elasticsearch Adapter
6
*/
7
Use Elasticsearch as ElasticsearchLib;
8
9
class ElasticSearch implements Base
10
{
11
    public $conn = null;
12
    private $index = null;
13
14
    public function __construct($config)
15
    {
16
        $this->index = $config['db_name'];
17
        $this->connect($config);
18
    }
19
20
    public function connect($config)
21
    {
22
        $this->conn = ElasticsearchLib\ClientBuilder::create()->setHosts($config['hosts'])->build();
23
    }
24
25
    public function create($collection, $config)
26
    {
27
    }
28
29
    public function drop($collection, $config)
30
    {
31
    }
32
33
    public function truncate($collection, $config)
34
    {
35
    }
36
37
    public function createIndexes($collection, $config)
38
    {
39
    }
40
41
    public function insert($collection, $values)
42
    {
43
        $params = [];
44
        $params['body'] = $values;
45
        $params['index'] = $this->index;
46
        $params['type'] = $collection;
47
        try {
48
            $result = $this->conn->index($params);
49
            if ($result['created']) {
50
                return $result['_id'];
51
            }
52
            return null;
53
        } catch (\Exception $e) {
54
            return;
55
        }
56
    }
57
58
    public function get($collection, $docId)
59
    {
60
        $params = [];
61
        $params['index'] = $this->index;
62
        $params['type'] = $collection;
63
64
        try {
65
            if (gettype($docId) == "array") {
66
                $params['body'] = [
67
                    'query' => [
68
                        'filtered' => [
69
                            'filter' => [
70
                                'ids' => ['values'=>$docId]
71
                            ],
72
                        ],
73
                    ],
74
                ];
75
                $results = $this->conn->search($params);
76
                if ($results['hits']['total'] == 0) {
77
                    return;
78
                }
79
                $result = [];
80
                foreach ($results['hits']['hits'] as $item){
81
                    $result[$item['_id']]=$item['_source'];
82
                }
83
                return $result;
84
            } else {
85
                $params['id'] = $docId;
86
                $result = $this->conn->get($params);
87
            }
88
            if ($result['found']) {
89
                $result['_source']['_id'] = $result['_id'];
90
                return $result['_source'];
91
            } else {
92
                return;
93
            }
94
        } catch (\Exception $e) {
95
            return;
96
        }
97
    }
98
99
    public function update($collection, $filter, $values)
100
    {
101
        $docs = $this->find($collection, $filter, ['_id']);
102
        if ($docs['total']===0) {
103
            return 0;
104
        }
105
        $params = [];
106
        $params['index'] = $this->index;
107
        $params['type'] = $collection;
108
        $modified_count = 0;
109
        foreach ($docs['data'] as $doc) {
110
            $params['id'] = $doc['_id'];
111
            $params['body']['doc'] = $values;
112
            try {
113
                $return = $this->conn->update($params);
114
                if ($return['_shards']['successful']==1) {
115
                    ++$modified_count;
116
                }
117
            } catch (\Exception $e) {
118
                // should we throw exception? Probably not.
119
            }
120
        }
121
122
        return $modified_count;
123
    }
124
125
    public function delete($collection, $filter)
126
    {
127
        if (isset($filter['_id'])) {
128
            $params = [];
129
            $params['index'] = $this->index;
130
            $params['type'] = $collection;
131
            $params['id'] = $filter['_id'];
132
            try {
133
                $result = $this->conn->delete($params);
134
            } catch (\Exception $e) {
135
                return 0;
136
            }
137
            if ($result['found']) {
138
                return 1;
139
            }
140
        } else {
141
            $params = [];
142
            $params['index'] = $this->index;
143
            $params['type'] = $collection;
144
            $params['fields'] = '_id';
145
            $result = $this->find('users', $filter, ['_id'], null, 0, 1);
146
            if ($result['total']==1) {
147
                $params = [];
148
                $params['index'] = $this->index;
149
                $params['type'] = $collection;
150
                $params['id'] = $result['data']['_id'];
151
                try {
152
                    $result = $this->conn->delete($params);
153
                } catch (\Exception $e) {
154
                    return 0;
155
                }
156
                if ($result['found']) {
157
                    return 1;
158
                }
159
            }
160
        }
161
162
        return 0;
163
    }
164
165
    public function find($collection, $filters, $fields = null, $sort = null, $start = 0, $limit = 25, $debug = false)
166
    {
167
        $return_type = '_source';
168
        $params = [];
169
        $params['index'] = $this->index;
170
        $params['type'] = $collection;
171
        if ($filters!==null) {
172
            $filters = self::buildFilter($filters);
173
            $params['body'] = [
174
                'query' => [
175
                    'filtered' => [
176
                        'filter' => [
177
                            'bool' => $filters,
178
                        ],
179
                    ],
180
                ],
181
            ];
182
        }
183
        $count = $this->conn->count($params);
184
        if ($fields!==null) {
185
            $params['fields'] = implode(',', $fields);
186
            $return_type = 'fields';
187
        }
188
        if ($sort!==null) {
189
            $params['sort'] = '';
190
            foreach ($sort as $sort_key => $sort_dir) {
191
                if ($params['sort']!='') {
192
                    $params['sort'] .= ',';
193
                }
194
                $params['sort'] .= $sort_key.':'.$sort_dir;
195
            }
196
        }
197
        if ($fields!='') {
198
            $params['fields'] = $fields;
199
            $return_type = 'fields';
200
        }
201
        $params['from'] = (int) $start;
202
        $params['size'] = (int) $limit;
203
        $return = $this->conn->search($params);
204
        if ($return['hits']['total']==0) {
205
            return ['total' => 0, 'data' => null];
206
        }
207
        elseif ($limit==1) {
208
            $return['hits']['hits'][0][$return_type]['_id'] = $return['hits']['hits'][0]['_id'];
209
            return ['total' => 1, 'data' => $return['hits']['hits'][0][$return_type]];
210
        }
211
        $result = array();
212
        foreach ($return['hits']['hits'] as $item) {
213
            if ($return_type=='fields') {
214
                foreach ($item[$return_type]as $k => $v) {
215
                    $item[$return_type][$k] = $v[0];
216
                }
217
            }
218
            $item[$return_type]['_id'] = $item['_id'];
219
            $result[] = $item[$return_type];
220
        }
221
        return ['total' => $count['count'], 'data' => $result];
222
    }
223
224
    public function query($query)
225
    {
226
        // reserved        
227
    }
228
229
    public static function buildFilter($filter)
230
    {
231
232
        $operators = [];
233
        $operators['range'] = ['gt', 'gte', 'lt', 'lte'];
234
        $operators['standart'] = ['prefix', 'regexp', 'wildchard'];
235
        $operators['BooleanQueryLevel'] = ['not'];
236
        $operators['special'] = ['in'];
237
238
        $filters = [];
239
        foreach ($filter as $key => $value) {
240
            $is_not = '';
241
            if (strpos($key, '__')!==false) {
242
                preg_match('/__(.*?)$/i', $key, $matches);
243
                $operator = $matches[1];
244
                if (strpos($operator, '!')===0) {
245
                    $operator = str_replace('!', '', $operator);
246
                    $is_not = '_not';
247
                }
248
                $key = str_replace($matches[0], '', $key);
249
                foreach ($operators as $type => $possibilities) {
250
                    if (in_array($operator, $possibilities)) {
251
                        switch ($type) {
252
                            case 'range':
253
                                $filters['must'.$is_not][] = ['range' => [$key => [$operator => $value]]];
254
                                break;
255
                            case 'standart':
256
                                $filters['must'.$is_not][] = [$type => [$key => $value]];
257
                                break;
258
                            case 'BooleanQueryLevel':
259
                                switch ($operator) {
260
                                    case 'not':
261
                                        $filters['must_not'][] = ['term' => [$key => $value]];
262
                                        break;
263
                                }
264
                                break;
265
                            case 'special':
266
                                switch ($operator) {
267
                                    case 'in':
268
                                        $filters['must'.$is_not][] = ['terms' => [$key => $value]];
269
                                        break;
270
                                }
271
                                break;
272
                        }
273
                    }
274
                }
275
            } elseif (strpos($key, '__')===false && is_array($value)) {
276
                foreach ($value as $skey => $svalue) {
277
                    if (strpos($skey, '__')!==false) {
278
                        preg_match('/__(.*?)$/i', $skey, $smatches);
279
                        $soperator = $smatches[1];
280
                        if (strpos($soperator, '!')===0) {
281
                            $soperator = str_replace('!', '', $soperator);
282
                        }
283
                        $skey = str_replace($smatches[0], '', $skey);
284
                        foreach ($operators as $type => $possibilities) {
285
                            if (in_array($soperator, $possibilities)) {
286
                                switch ($type) {
287
                                    case 'range':
288
                                        $filters['should'][] = ['range' => [$skey => [$soperator => $svalue]]];
289
                                        break;
290
                                    case 'standart':
291
                                        $filters['should'][] = [$type => [$skey => $svalue]];
292
                                        break;
293
                                    case 'special':
294
                                        switch ($soperator) {
295
                                            case 'in':
296
                                                $filters['should'][] = ['terms' => [$skey => $svalue]];
297
                                                break;
298
                                        }
299
                                        break;
300
                                }
301
                            }
302
                        }
303
                    } else {
304
                        $filters['should'][] = ['term' => [$skey => $svalue]];
305
                    }
306
                }
307
            } else {
308
                $filters['must'][] = ['term' => [$key => $value]];
309
            }
310
        }
311
        return $filters;
312
    }
313
}
314