Completed
Push — master ( 3a2d29...d0475e )
by Nicolas
02:57
created

lib/Elastica/Index.php (2 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
namespace Elastica;
3
4
use Elastica\Exception\InvalidException;
5
use Elastica\Exception\ResponseException;
6
use Elastica\Index\Settings as IndexSettings;
7
use Elastica\Index\Stats as IndexStats;
8
use Elastica\ResultSet\BuilderInterface;
9
10
/**
11
 * Elastica index object.
12
 *
13
 * Handles reads, deletes and configurations of an index
14
 *
15
 * @author   Nicolas Ruflin <[email protected]>
16
 */
17
class Index implements SearchableInterface
18
{
19
    /**
20
     * Index name.
21
     *
22
     * @var string Index name
23
     */
24
    protected $_name;
25
26
    /**
27
     * Client object.
28
     *
29
     * @var \Elastica\Client Client object
30
     */
31
    protected $_client;
32
33
    /**
34
     * Creates a new index object.
35
     *
36
     * All the communication to and from an index goes of this object
37
     *
38
     * @param \Elastica\Client $client Client object
39
     * @param string           $name   Index name
40
     */
41 View Code Duplication
    public function __construct(Client $client, $name)
42
    {
43
        $this->_client = $client;
44
45
        if (!is_scalar($name)) {
46
            throw new InvalidException('Index name should be a scalar type');
47
        }
48
        $this->_name = (string) $name;
49
    }
50
51
    /**
52
     * Returns a type object for the current index with the given name.
53
     *
54
     * @param string $type Type name
55
     *
56
     * @return \Elastica\Type Type object
57
     */
58
    public function getType($type)
59
    {
60
        return new Type($this, $type);
61
    }
62
63
    /**
64
     * Return Index Stats.
65
     *
66
     * @return \Elastica\Index\Stats
67
     */
68
    public function getStats()
69
    {
70
        return new IndexStats($this);
71
    }
72
73
    /**
74
     * Gets all the type mappings for an index.
75
     *
76
     * @return array
77
     */
78 View Code Duplication
    public function getMapping()
79
    {
80
        $path = '_mapping';
81
82
        $response = $this->request($path, Request::GET);
83
        $data = $response->getData();
84
85
        // Get first entry as if index is an Alias, the name of the mapping is the real name and not alias name
86
        $mapping = array_shift($data);
87
88
        if (isset($mapping['mappings'])) {
89
            return $mapping['mappings'];
90
        }
91
92
        return [];
93
    }
94
95
    /**
96
     * Returns the index settings object.
97
     *
98
     * @return \Elastica\Index\Settings Settings object
99
     */
100
    public function getSettings()
101
    {
102
        return new IndexSettings($this);
103
    }
104
105
    /**
106
     * Uses _bulk to send documents to the server.
107
     *
108
     * @param array|\Elastica\Document[] $docs Array of Elastica\Document
109
     *
110
     * @return \Elastica\Bulk\ResponseSet
111
     *
112
     * @link https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-bulk.html
113
     */
114
    public function updateDocuments(array $docs)
115
    {
116
        foreach ($docs as $doc) {
117
            $doc->setIndex($this->getName());
118
        }
119
120
        return $this->getClient()->updateDocuments($docs);
121
    }
122
123
    /**
124
     * Uses _bulk to send documents to the server.
125
     *
126
     * @param array|\Elastica\Document[] $docs Array of Elastica\Document
127
     *
128
     * @return \Elastica\Bulk\ResponseSet
129
     *
130
     * @link https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-bulk.html
131
     */
132
    public function addDocuments(array $docs)
133
    {
134
        foreach ($docs as $doc) {
135
            $doc->setIndex($this->getName());
136
        }
137
138
        return $this->getClient()->addDocuments($docs);
139
    }
140
141
    /**
142
     * Deletes entries in the db based on a query.
143
     *
144
     * @param \Elastica\Query|string|array $query   Query object or array
145
     * @param array                        $options Optional params
146
     *
147
     * @return \Elastica\Response
148
     *
149
     * @link https://www.elastic.co/guide/en/elasticsearch/reference/5.0/docs-delete-by-query.html
150
     */
151
    public function deleteByQuery($query, array $options = [])
152
    {
153
        $query = Query::create($query)->getQuery();
154
155
        return $this->request('_delete_by_query', Request::POST, ['query' => is_array($query) ? $query : $query->toArray()], $options);
156
    }
157
158
    /**
159
     * Deletes the index.
160
     *
161
     * @return \Elastica\Response Response object
162
     */
163
    public function delete()
164
    {
165
        $response = $this->request('', Request::DELETE);
166
167
        return $response;
168
    }
169
170
    /**
171
     * Uses _bulk to delete documents from the server.
172
     *
173
     * @param array|\Elastica\Document[] $docs Array of Elastica\Document
174
     *
175
     * @return \Elastica\Bulk\ResponseSet
176
     *
177
     * @link https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-bulk.html
178
     */
179
    public function deleteDocuments(array $docs)
180
    {
181
        foreach ($docs as $doc) {
182
            $doc->setIndex($this->getName());
183
        }
184
185
        return $this->getClient()->deleteDocuments($docs);
186
    }
187
188
    /**
189
     * Optimizes search index.
190
     *
191
     * Detailed arguments can be found here in the link
192
     *
193
     * @param array $args OPTIONAL Additional arguments
194
     *
195
     * @return array Server response
196
     *
197
     * @deprecated Replaced by forcemerge
198
     * @link https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-optimize.html
199
     */
200
    public function optimize($args = [])
201
    {
202
        trigger_error('Deprecated: Elastica\Index::optimize() is deprecated and will be removed in further Elastica releases. Use Elastica\Query::forcemerge() instead.', E_USER_DEPRECATED);
203
204
        return $this->forcemerge($args);
205
    }
206
207
    /**
208
     * Force merges index.
209
     *
210
     * Detailed arguments can be found here in the link
211
     *
212
     * @param array $args OPTIONAL Additional arguments
213
     *
214
     * @return array Server response
215
     *
216
     * @link https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-forcemerge.html
217
     */
218
    public function forcemerge($args = [])
219
    {
220
        return $this->request('_forcemerge', Request::POST, [], $args);
221
    }
222
223
    /**
224
     * Refreshes the index.
225
     *
226
     * @return \Elastica\Response Response object
227
     *
228
     * @link https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-refresh.html
229
     */
230
    public function refresh()
231
    {
232
        return $this->request('_refresh', Request::POST, []);
233
    }
234
235
    /**
236
     * Creates a new index with the given arguments.
237
     *
238
     * @link https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-create-index.html
239
     *
240
     * @param array      $args    OPTIONAL Arguments to use
241
     * @param bool|array $options OPTIONAL
242
     *                            bool=> Deletes index first if already exists (default = false).
243
     *                            array => Associative array of options (option=>value)
244
     *
245
     * @throws \Elastica\Exception\InvalidException
246
     * @throws \Elastica\Exception\ResponseException
247
     *
248
     * @return \Elastica\Response Server response
249
     */
250
    public function create(array $args = [], $options = null)
251
    {
252
        $path = '';
253
        $query = [];
254
255
        if (is_bool($options)) {
256
            if ($options) {
257
                try {
258
                    $this->delete();
259
                } catch (ResponseException $e) {
260
                    // Table can't be deleted, because doesn't exist
261
                }
262
            }
263
        } else {
264
            if (is_array($options)) {
265
                foreach ($options as $key => $value) {
266
                    switch ($key) {
267
                        case 'recreate':
268
                            try {
269
                                $this->delete();
270
                            } catch (ResponseException $e) {
271
                                // Table can't be deleted, because doesn't exist
272
                            }
273
                            break;
274
                        case 'routing':
275
                            $query = ['routing' => $value];
276
                            break;
277
                        default:
278
                            throw new InvalidException('Invalid option '.$key);
279
                            break;
0 ignored issues
show
break; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
280
                    }
281
                }
282
            }
283
        }
284
285
        return $this->request($path, Request::PUT, $args, $query);
286
    }
287
288
    /**
289
     * Checks if the given index is already created.
290
     *
291
     * @return bool True if index exists
292
     */
293 View Code Duplication
    public function exists()
294
    {
295
        $response = $this->getClient()->request($this->getName(), Request::HEAD);
296
        $info = $response->getTransferInfo();
297
298
        return (bool) ($info['http_code'] == 200);
299
    }
300
301
    /**
302
     * @param string|array|\Elastica\Query $query
303
     * @param int|array                    $options
304
     * @param BuilderInterface             $builder
305
     *
306
     * @return Search
307
     */
308
    public function createSearch($query = '', $options = null, BuilderInterface $builder = null)
309
    {
310
        $search = new Search($this->getClient(), $builder);
311
        $search->addIndex($this);
312
        $search->setOptionsAndQuery($options, $query);
313
314
        return $search;
315
    }
316
317
    /**
318
     * Searches in this index.
319
     *
320
     * @param string|array|\Elastica\Query $query   Array with all query data inside or a Elastica\Query object
321
     * @param int|array                    $options OPTIONAL Limit or associative array of options (option=>value)
322
     *
323
     * @return \Elastica\ResultSet with all results inside
324
     *
325
     * @see \Elastica\SearchableInterface::search
326
     */
327
    public function search($query = '', $options = null)
328
    {
329
        $search = $this->createSearch($query, $options);
330
331
        return $search->search();
332
    }
333
334
    /**
335
     * Counts results of query.
336
     *
337
     * @param string|array|\Elastica\Query $query Array with all query data inside or a Elastica\Query object
338
     *
339
     * @return int number of documents matching the query
340
     *
341
     * @see \Elastica\SearchableInterface::count
342
     */
343
    public function count($query = '')
344
    {
345
        $search = $this->createSearch($query);
346
347
        return $search->count();
0 ignored issues
show
Bug Compatibility introduced by
The expression $search->count(); of type Elastica\ResultSet|integer adds the type Elastica\ResultSet to the return on line 347 which is incompatible with the return type declared by the interface Elastica\SearchableInterface::count of type integer.
Loading history...
348
    }
349
350
    /**
351
     * Opens an index.
352
     *
353
     * @return \Elastica\Response Response object
354
     *
355
     * @link https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-open-close.html
356
     */
357
    public function open()
358
    {
359
        return $this->request('_open', Request::POST);
360
    }
361
362
    /**
363
     * Closes the index.
364
     *
365
     * @return \Elastica\Response Response object
366
     *
367
     * @link https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-open-close.html
368
     */
369
    public function close()
370
    {
371
        return $this->request('_close', Request::POST);
372
    }
373
374
    /**
375
     * Returns the index name.
376
     *
377
     * @return string Index name
378
     */
379
    public function getName()
380
    {
381
        return $this->_name;
382
    }
383
384
    /**
385
     * Returns index client.
386
     *
387
     * @return \Elastica\Client Index client object
388
     */
389
    public function getClient()
390
    {
391
        return $this->_client;
392
    }
393
394
    /**
395
     * Adds an alias to the current index.
396
     *
397
     * @param string $name    Alias name
398
     * @param bool   $replace OPTIONAL If set, an existing alias will be replaced
399
     *
400
     * @return \Elastica\Response Response
401
     *
402
     * @link https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-aliases.html
403
     */
404
    public function addAlias($name, $replace = false)
405
    {
406
        $path = '_aliases';
407
408
        $data = ['actions' => []];
409
410
        if ($replace) {
411
            $status = new Status($this->getClient());
412
            foreach ($status->getIndicesWithAlias($name) as $index) {
413
                $data['actions'][] = ['remove' => ['index' => $index->getName(), 'alias' => $name]];
414
            }
415
        }
416
417
        $data['actions'][] = ['add' => ['index' => $this->getName(), 'alias' => $name]];
418
419
        return $this->getClient()->request($path, Request::POST, $data);
420
    }
421
422
    /**
423
     * Removes an alias pointing to the current index.
424
     *
425
     * @param string $name Alias name
426
     *
427
     * @return \Elastica\Response Response
428
     *
429
     * @link https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-aliases.html
430
     */
431
    public function removeAlias($name)
432
    {
433
        $path = '_aliases';
434
435
        $data = ['actions' => [['remove' => ['index' => $this->getName(), 'alias' => $name]]]];
436
437
        return $this->getClient()->request($path, Request::POST, $data);
438
    }
439
440
    /**
441
     * Returns all index aliases.
442
     *
443
     * @return array Aliases
444
     */
445
    public function getAliases()
446
    {
447
        $responseData = $this->request('_alias/*', \Elastica\Request::GET)->getData();
448
449
        if (!isset($responseData[$this->getName()])) {
450
            return [];
451
        }
452
453
        $data = $responseData[$this->getName()];
454
        if (!empty($data['aliases'])) {
455
            return array_keys($data['aliases']);
456
        }
457
458
        return [];
459
    }
460
461
    /**
462
     * Checks if the index has the given alias.
463
     *
464
     * @param string $name Alias name
465
     *
466
     * @return bool
467
     */
468
    public function hasAlias($name)
469
    {
470
        return in_array($name, $this->getAliases());
471
    }
472
473
    /**
474
     * Clears the cache of an index.
475
     *
476
     * @return \Elastica\Response Response object
477
     *
478
     * @link https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-clearcache.html
479
     */
480
    public function clearCache()
481
    {
482
        $path = '_cache/clear';
483
        // TODO: add additional cache clean arguments
484
        return $this->request($path, Request::POST);
485
    }
486
487
    /**
488
     * Flushes the index to storage.
489
     *
490
     * @param array $options
491
     *
492
     * @return Response Response object
493
     *
494
     * @link https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-flush.html
495
     */
496
    public function flush(array $options = [])
497
    {
498
        $path = '_flush';
499
500
        return $this->request($path, Request::POST, [], $options);
501
    }
502
503
    /**
504
     * Can be used to change settings during runtime. One example is to use it for bulk updating.
505
     *
506
     * @param array $data Data array
507
     *
508
     * @return \Elastica\Response Response object
509
     *
510
     * @link https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-update-settings.html
511
     */
512
    public function setSettings(array $data)
513
    {
514
        return $this->request('_settings', Request::PUT, $data);
515
    }
516
517
    /**
518
     * Makes calls to the elasticsearch server based on this index.
519
     *
520
     * @param string       $path   Path to call
521
     * @param string       $method Rest method to use (GET, POST, DELETE, PUT)
522
     * @param array|string $data   OPTIONAL Arguments as array or encoded string
523
     * @param array        $query  OPTIONAL Query params
524
     *
525
     * @return \Elastica\Response Response object
526
     */
527
    public function request($path, $method, $data = [], array $query = [])
528
    {
529
        $path = $this->getName().'/'.$path;
530
531
        return $this->getClient()->request($path, $method, $data, $query);
532
    }
533
534
    /**
535
     * Analyzes a string.
536
     *
537
     * Detailed arguments can be found here in the link
538
     *
539
     * @param string $text String to be analyzed
540
     * @param array  $args OPTIONAL Additional arguments
541
     *
542
     * @return array Server response
543
     *
544
     * @link https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-analyze.html
545
     */
546
    public function analyze($text, $args = [])
547
    {
548
        $data = $this->request('_analyze', Request::POST, $text, $args)->getData();
549
550
        return $data['tokens'];
551
    }
552
}
553