Index   F
last analyzed

Complexity

Total Complexity 72

Size/Duplication

Total Lines 442
Duplicated Lines 0 %

Importance

Changes 5
Bugs 0 Features 0
Metric Value
eloc 232
c 5
b 0
f 0
dl 0
loc 442
rs 2.64
wmc 72

33 Methods

Rating   Name   Duplication   Size   Complexity  
A search() 0 5 1
A getDocumentById() 0 13 2
A truncate() 0 6 1
A optimize() 0 9 2
A updateDocuments() 0 16 3
A percolate() 0 13 4
A checkDocumentId() 0 6 3
A flush() 0 6 1
A drop() 0 9 2
A deleteDocument() 0 13 2
A checkIfList() 0 4 3
A getClient() 0 3 1
A replaceDocument() 0 19 4
A describe() 0 6 1
A addDocument() 0 20 4
A deleteDocuments() 0 15 3
A explainQuery() 0 9 1
A deleteDocumentsByIds() 0 17 2
A setName() 0 4 1
B addDocuments() 0 27 6
A status() 0 6 1
A getDocumentByIds() 0 19 2
A getName() 0 3 1
A create() 0 13 2
A keywords() 0 10 1
A setCluster() 0 4 1
A alter() 0 22 3
A updateDocument() 0 14 2
A flushramchunk() 0 6 1
A percolateToDocs() 0 13 4
A suggest() 0 10 1
A replaceDocuments() 0 23 5
A __construct() 0 5 1

How to fix   Complexity   

Complex Class

Complex classes like Index often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Index, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
4
namespace Manticoresearch;
5
6
use Manticoresearch\Exceptions\RuntimeException;
7
use Manticoresearch\Query\Percolate;
8
use Manticoresearch\Results;
9
10
/**
11
 * Manticore index object
12
 * @category ManticoreSearch
13
 * @package ManticoreSearch
14
 * @author Adrian Nuta <[email protected]>
15
 * @link https://manticoresearch.com
16
 */
17
class Index
18
{
19
    use Utils;
20
21
    protected $client;
22
    protected $index;
23
    protected $cluster = null;
24
25
    public function __construct(Client $client, $index = null)
26
    {
27
        $this->client = $client;
28
29
        $this->index = $index;
30
    }
31
32
    public function search($input): Search
33
    {
34
        $search = new Search($this->client);
35
        $search->setIndex($this->index);
36
        return $search->search($input);
37
    }
38
39
    public function getDocumentById($id)
40
    {
41
        static::checkDocumentId($id);
42
        $params = [
43
            'body' => [
44
                'index' => $this->index,
45
                'query' => [
46
                    'equals' => ['id' => $id]
47
                ]
48
            ]
49
        ];
50
        $result = new ResultSet($this->client->search($params, true));
51
        return $result->valid() ? $result->current() : null;
52
    }
53
54
    public function getDocumentByIds($ids)
55
    {
56
        if (!is_array($ids)) {
57
            $ids = [$ids];
58
        }
59
        // Deduplicate and order the list
60
        static::checkIfList($ids);
61
62
        array_walk($ids, [static::class, 'checkDocumentId']);
63
        $params = [
64
            'body' => [
65
                'index' => $this->index,
66
                'limit' => sizeof($ids),
67
                'query' => [
68
                    'in' => ['id' => $ids]
69
                ]
70
            ]
71
        ];
72
        return new ResultSet($this->client->search($params, true));
73
    }
74
75
    public function addDocument($data, $id = 0)
76
    {
77
        static::checkDocumentId($id);
78
        if (is_object($data)) {
79
            $data = (array) $data;
80
        } elseif (is_string($data)) {
81
            $data = json_decode($data, true);
82
        }
83
        $params = [
84
            'body' => [
85
                'index' => $this->index,
86
                'id' => $id,
87
                'doc' => $data
88
            ]
89
        ];
90
91
        if ($this->cluster !== null) {
92
            $params['body']['cluster'] = $this->cluster;
93
        }
94
        return $this->client->insert($params);
95
    }
96
97
    public function addDocuments($documents)
98
    {
99
        $toinsert = [];
100
        foreach ($documents as $document) {
101
            if (is_object($document)) {
102
                $document = (array) $document;
103
            } elseif (is_string($document)) {
104
                $document = json_decode($document, true);
105
            }
106
            if (isset($document['id'])) {
107
                $id = $document['id'];
108
                static::checkDocumentId($id);
109
                unset($document['id']);
110
            } else {
111
                $id = 0;
112
            }
113
            $insert = [
114
                'index' => $this->index,
115
                'id' => $id,
116
                'doc' => $document
117
            ];
118
            if ($this->cluster !== null) {
119
                $insert['cluster'] = $this->cluster;
120
            }
121
            $toinsert[] = ['insert' => $insert];
122
        }
123
        return $this->client->bulk(['body' => $toinsert]);
124
    }
125
126
    public function deleteDocument($id)
127
    {
128
        static::checkDocumentId($id);
129
        $params = [
130
            'body' => [
131
                'index' => $this->index,
132
                'id' => $id
133
            ]
134
        ];
135
        if ($this->cluster !== null) {
136
            $params['body']['cluster'] = $this->cluster;
137
        }
138
        return $this->client->delete($params);
139
    }
140
141
    public function deleteDocumentsByIds(array $ids)
142
    {
143
        // Deduplicate and order the list
144
        static::checkIfList($ids);
145
146
        array_walk($ids, 'self::checkDocumentId');
147
        $params = [
148
            'body' => [
149
                'index' => $this->index,
150
                'limit' => sizeof($ids),
151
                'id' => $ids
152
            ]
153
        ];
154
        if ($this->cluster !== null) {
155
            $params['body']['cluster'] = $this->cluster;
156
        }
157
        return $this->client->delete($params);
158
    }
159
160
    public function deleteDocuments($query)
161
    {
162
        if ($query instanceof Query) {
163
            $query = $query->toArray();
164
        }
165
        $params = [
166
            'body' => [
167
                'index' => $this->index,
168
                'query' => $query
169
            ]
170
        ];
171
        if ($this->cluster !== null) {
172
            $params['body']['cluster'] = $this->cluster;
173
        }
174
        return $this->client->delete($params);
175
    }
176
177
    public function updateDocument($data, $id)
178
    {
179
        static::checkDocumentId($id);
180
        $params = [
181
            'body' => [
182
                'index' => $this->index,
183
                'id' => $id,
184
                'doc' => $data
185
            ]
186
        ];
187
        if ($this->cluster !== null) {
188
            $params['body']['cluster'] = $this->cluster;
189
        }
190
        return $this->client->update($params);
191
    }
192
193
    public function updateDocuments($data, $query)
194
    {
195
        if ($query instanceof Query) {
196
            $query = $query->toArray();
197
        }
198
        $params = [
199
            'body' => [
200
                'index' => $this->index,
201
                'query' => $query,
202
                'doc' => $data
203
            ]
204
        ];
205
        if ($this->cluster !== null) {
206
            $params['body']['cluster'] = $this->cluster;
207
        }
208
        return $this->client->update($params);
209
    }
210
211
    public function replaceDocument($data, $id)
212
    {
213
        static::checkDocumentId($id);
214
        if (is_object($data)) {
215
            $data = (array) $data;
216
        } elseif (is_string($data)) {
217
            $data = json_decode($data, true);
218
        }
219
        $params = [
220
            'body' => [
221
                'index' => $this->index,
222
                'id' => $id,
223
                'doc' => $data
224
            ]
225
        ];
226
        if ($this->cluster !== null) {
227
            $params['body']['cluster'] = $this->cluster;
228
        }
229
        return $this->client->replace($params);
230
    }
231
232
    public function replaceDocuments($documents)
233
    {
234
        $toreplace = [];
235
        foreach ($documents as $document) {
236
            if (is_object($document)) {
237
                $document = (array) $document;
238
            } elseif (is_string($document)) {
239
                $document = json_decode($document, true);
240
            }
241
            $id = $document['id'];
242
            static::checkDocumentId($id);
243
            unset($document['id']);
244
            $replace = [
245
                'index' => $this->index,
246
                'id' => $id,
247
                'doc' => $document
248
            ];
249
            if ($this->cluster !== null) {
250
                $replace['cluster'] = $this->cluster;
251
            }
252
            $toreplace[] = ['replace' => $replace];
253
        }
254
        return $this->client->bulk(['body' => $toreplace]);
255
    }
256
257
    public function create($fields, $settings = [], $silent = false)
258
    {
259
        $params = [
260
            'index' => $this->index,
261
            'body' => [
262
                'columns' => $fields,
263
                'settings' => $settings
264
            ]
265
        ];
266
        if ($silent === true) {
267
            $params['body']['silent'] = true;
268
        }
269
        return $this->client->indices()->create($params);
270
    }
271
272
    public function drop($silent = false)
273
    {
274
        $params = [
275
            'index' => $this->index,
276
        ];
277
        if ($silent === true) {
278
            $params['body'] = ['silent' => true];
279
        }
280
        return $this->client->indices()->drop($params);
281
    }
282
283
    public function describe()
284
    {
285
        $params = [
286
            'index' => $this->index,
287
        ];
288
        return $this->client->indices()->describe($params);
289
    }
290
291
    public function status()
292
    {
293
        $params = [
294
            'index' => $this->index,
295
        ];
296
        return $this->client->indices()->status($params);
297
    }
298
299
    public function truncate()
300
    {
301
        $params = [
302
            'index' => $this->index,
303
        ];
304
        return $this->client->indices()->truncate($params);
305
    }
306
307
    public function optimize($sync = false)
308
    {
309
        $params = [
310
            'index' => $this->index,
311
        ];
312
        if ($sync === true) {
313
            $params['body'] = ['sync' => true];
314
        }
315
        return $this->client->indices()->optimize($params);
316
    }
317
318
    public function flush()
319
    {
320
        $params = [
321
            'index' => $this->index,
322
        ];
323
        $this->client->indices()->flushrtindex($params);
324
    }
325
326
    public function flushramchunk()
327
    {
328
        $params = [
329
            'index' => $this->index,
330
        ];
331
        $this->client->indices()->flushramchunk($params);
332
    }
333
334
    public function alter($operation, $name, $type = null)
335
    {
336
        if ($operation === 'add') {
337
            $params = [
338
                'index' => $this->index,
339
                'body' => [
340
                    'operation' => 'add',
341
                    'column' => ['name' => $name, 'type' => $type]
342
                ]
343
            ];
344
        } elseif ($operation === 'drop') {
345
            $params = [
346
                'index' => $this->index,
347
                'body' => [
348
                    'operation' => 'drop',
349
                    'column' => ['name' => $name]
350
                ]
351
            ];
352
        } else {
353
            throw new RuntimeException('Alter operation not recognized');
354
        }
355
        return $this->client->indices()->alter($params);
356
    }
357
358
    public function keywords($query, $options)
359
    {
360
        $params = [
361
            'index' => $this->index,
362
            'body' => [
363
                'query' => $query,
364
                'options' => $options
365
            ]
366
        ];
367
        return $this->client->keywords($params);
368
    }
369
370
    public function suggest($query, $options)
371
    {
372
        $params = [
373
            'index' => $this->index,
374
            'body' => [
375
                'query' => $query,
376
                'options' => $options
377
            ]
378
        ];
379
        return $this->client->suggest($params);
380
    }
381
382
    public function explainQuery($query)
383
    {
384
        $params = [
385
            'index' => $this->index,
386
            'body' => [
387
                'query' => $query,
388
            ]
389
        ];
390
        return $this->client->explainQuery($params);
391
    }
392
393
394
    public function percolate($docs)
395
    {
396
        $params = ['index' => $this->index, 'body' => []];
397
        if ($docs instanceof Percolate) {
398
            $params['body']['query'] = $docs->toArray();
399
        } else {
400
            if (isset($docs[0]) && is_array($docs[0])) {
401
                $params['body']['query'] = ['percolate' => ['documents' => $docs]];
402
            } else {
403
                $params['body']['query'] = ['percolate' => ['document' => $docs]];
404
            }
405
        }
406
        return new Results\PercolateResultSet($this->client->pq()->search($params, true));
407
    }
408
409
    public function percolateToDocs($docs)
410
    {
411
        $params = ['index' => $this->index, 'body' => []];
412
        if ($docs instanceof Percolate) {
413
            $params['body']['query'] = $docs->toArray();
414
        } else {
415
            if (isset($docs[0]) && is_array($docs[0])) {
416
                $params['body']['query'] = ['percolate' => ['documents' => $docs]];
417
            } else {
418
                $params['body']['query'] = ['percolate' => ['document' => $docs]];
419
            }
420
        }
421
        return new Results\PercolateDocsResultSet($this->client->pq()->search($params, true), $docs);
422
    }
423
424
425
    public function getClient(): Client
426
    {
427
        return $this->client;
428
    }
429
430
    public function getName(): string
431
    {
432
        return $this->index;
433
    }
434
435
    public function setName($index): self
436
    {
437
        $this->index = $index;
438
        return $this;
439
    }
440
441
    public function setCluster($cluster): self
442
    {
443
        $this->cluster = $cluster;
444
        return $this;
445
    }
446
447
    protected static function checkDocumentId(&$id)
448
    {
449
        if (is_string($id) && !is_numeric($id)) {
450
            throw new RuntimeException('Incorrect document id passed');
451
        }
452
        $id = (int)$id;
453
    }
454
    
455
    protected static function checkIfList(array &$ids)
456
    {
457
        if ($ids && (array_keys($ids) !== range(0, count($ids) - 1))) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $ids of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
458
            $ids = array_values(array_unique($ids));
459
        }
460
    }
461
}
462