Completed
Pull Request — master (#67)
by
unknown
02:12
created

Search::getSuggests()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
3
/*
4
 * This file is part of the ONGR package.
5
 *
6
 * (c) NFQ Technologies UAB <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace ONGR\ElasticsearchDSL;
13
14
use ONGR\ElasticsearchDSL\Aggregation\AbstractAggregation;
15
use ONGR\ElasticsearchDSL\Highlight\Highlight;
16
use ONGR\ElasticsearchDSL\Query\BoolQuery;
17
use ONGR\ElasticsearchDSL\SearchEndpoint\AbstractSearchEndpoint;
18
use ONGR\ElasticsearchDSL\SearchEndpoint\AggregationsEndpoint;
19
use ONGR\ElasticsearchDSL\SearchEndpoint\FilterEndpoint;
20
use ONGR\ElasticsearchDSL\SearchEndpoint\HighlightEndpoint;
21
use ONGR\ElasticsearchDSL\SearchEndpoint\PostFilterEndpoint;
22
use ONGR\ElasticsearchDSL\SearchEndpoint\QueryEndpoint;
23
use ONGR\ElasticsearchDSL\SearchEndpoint\SearchEndpointFactory;
24
use ONGR\ElasticsearchDSL\SearchEndpoint\SearchEndpointInterface;
25
use ONGR\ElasticsearchDSL\SearchEndpoint\SortEndpoint;
26
use ONGR\ElasticsearchDSL\Serializer\Normalizer\CustomReferencedNormalizer;
27
use ONGR\ElasticsearchDSL\Serializer\OrderedSerializer;
28
use Symfony\Component\Serializer\Normalizer\CustomNormalizer;
29
use ONGR\ElasticsearchDSL\SearchEndpoint\SuggestEndpoint;
30
use ONGR\ElasticsearchDSL\Suggest\Suggest;
31
32
/**
33
 * Search object that can be executed by a manager.
34
 */
35
class Search
36
{
37
    /**
38
     * @var int
39
     */
40
    private $size;
41
42
    /**
43
     * @var int
44
     */
45
    private $from;
46
47
    /**
48
     * @var string
49
     */
50
    private $timeout;
51
52
    /**
53
     * @var int
54
     */
55
    private $terminateAfter;
56
57
    /**
58
     * @var string|null
59
     */
60
    private $scroll;
61
62
    /**
63
     * @var array|bool|string
64
     */
65
    private $source;
66
67
    /**
68
     * @var array
69
     */
70
    private $fields;
71
72
    /**
73
     * @var array
74
     */
75
    private $scriptFields;
76
77
    /**
78
     * @var string
79
     */
80
    private $searchType;
81
82
    /**
83
     * @var string
84
     */
85
    private $requestCache;
86
87
    /**
88
     * @var bool
89
     */
90
    private $explain;
91
92
    /**
93
     * @var array
94
     */
95
    private $stats;
96
97
    /**
98
     * @var string[]
99
     */
100
    private $preference;
101
102
    /**
103
     * @var float
104
     */
105
    private $minScore;
106
107
    /**
108
     * @var OrderedSerializer
109
     */
110
    private $serializer;
111
112
    /**
113
     * @var SearchEndpointInterface[]
114
     */
115
    private $endpoints = [];
116
117
    /**
118
     * Initializes serializer.
119
     */
120
    public function __construct()
121
    {
122
        $this->serializer = new OrderedSerializer(
123
            [
124
                new CustomReferencedNormalizer(),
125
                new CustomNormalizer(),
126
            ]
127
        );
128
    }
129
130
    /**
131
     * Returns endpoint instance.
132
     *
133
     * @param string $type Endpoint type.
134
     *
135
     * @return SearchEndpointInterface
136
     */
137
    private function getEndpoint($type)
138
    {
139
        if (!array_key_exists($type, $this->endpoints)) {
140
            $this->endpoints[$type] = SearchEndpointFactory::get($type);
141
        }
142
143
        return $this->endpoints[$type];
144
    }
145
146
    /**
147
     * Destroys search endpoint.
148
     *
149
     * @param string $type Endpoint type.
150
     */
151
    public function destroyEndpoint($type)
152
    {
153
        unset($this->endpoints[$type]);
154
    }
155
156
    /**
157
     * Sets parameters to the endpoint.
158
     *
159
     * @param string $endpointName
160
     * @param array  $parameters
161
     */
162
    private function setEndpointParameters($endpointName, array $parameters)
163
    {
164
        /** @var AbstractSearchEndpoint $endpoint */
165
        $endpoint = $this->getEndpoint($endpointName);
166
        $endpoint->setParameters($parameters);
167
    }
168
169
    /**
170
     * Adds query to the search.
171
     *
172
     * @param BuilderInterface $query
173
     * @param string           $boolType
174
     * @param string           $key
175
     *
176
     * @return $this
177
     */
178 View Code Duplication
    public function addQuery(BuilderInterface $query, $boolType = BoolQuery::MUST, $key = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
179
    {
180
        $endpoint = $this->getEndpoint(QueryEndpoint::NAME);
181
        $endpoint->addToBool($query, $boolType, $key);
0 ignored issues
show
Documentation introduced by
$boolType is of type string, but the function expects a array|null.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
Bug introduced by
It seems like $key defined by parameter $key on line 178 can also be of type string; however, ONGR\ElasticsearchDSL\Se...tInterface::addToBool() does only seem to accept array|null, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
182
183
        return $this;
184
    }
185
186
    /**
187
     * Returns queries inside BoolQuery instance.
188
     *
189
     * @return BuilderInterface
190
     */
191
    public function getQueries()
192
    {
193
        $endpoint = $this->getEndpoint(QueryEndpoint::NAME);
194
195
        return $endpoint->getBool();
196
    }
197
198
    /**
199
     * Sets query endpoint parameters.
200
     *
201
     * @param array $parameters
202
     *
203
     * @return $this
204
     */
205
    public function setQueryParameters(array $parameters)
206
    {
207
        $this->setEndpointParameters(QueryEndpoint::NAME, $parameters);
208
209
        return $this;
210
    }
211
212
    /**
213
     * Adds a filter to the search.
214
     *
215
     * @param BuilderInterface $filter   Filter.
216
     * @param string           $boolType Example boolType values:
217
     *                                   - must
218
     *                                   - must_not
219
     *                                   - should.
220
     * @param string           $key
221
     *
222
     * @return $this
223
     */
224 View Code Duplication
    public function addFilter(BuilderInterface $filter, $boolType = BoolQuery::MUST, $key = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
225
    {
226
        // Trigger creation of QueryEndpoint as filters depends on it
227
        $this->getEndpoint(QueryEndpoint::NAME);
228
229
        $endpoint = $this->getEndpoint(FilterEndpoint::NAME);
230
        $endpoint->addToBool($filter, $boolType, $key);
0 ignored issues
show
Documentation introduced by
$boolType is of type string, but the function expects a array|null.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
Bug introduced by
It seems like $key defined by parameter $key on line 224 can also be of type string; however, ONGR\ElasticsearchDSL\Se...tInterface::addToBool() does only seem to accept array|null, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
231
232
        return $this;
233
    }
234
235
    /**
236
     * Returns queries inside BoolFilter instance.
237
     *
238
     * @return BuilderInterface
239
     */
240
    public function getFilters()
241
    {
242
        $endpoint = $this->getEndpoint(FilterEndpoint::NAME);
243
244
        return $endpoint->getBool();
245
    }
246
247
    /**
248
     * Sets filter endpoint parameters.
249
     *
250
     * @param array $parameters
251
     *
252
     * @return $this
253
     */
254
    public function setFilterParameters(array $parameters)
255
    {
256
        $this->setEndpointParameters(FilterEndpoint::NAME, $parameters);
257
258
        return $this;
259
    }
260
261
    /**
262
     * Adds a post filter to search.
263
     *
264
     * @param BuilderInterface $filter   Filter.
265
     * @param string           $boolType Example boolType values:
266
     *                                   - must
267
     *                                   - must_not
268
     *                                   - should.
269
     * @param string           $key
270
     *
271
     * @return int Key of post filter.
272
     */
273
    public function addPostFilter(BuilderInterface $filter, $boolType = BoolQuery::MUST, $key = null)
274
    {
275
        $this
276
            ->getEndpoint(PostFilterEndpoint::NAME)
277
            ->addToBool($filter, $boolType, $key);
0 ignored issues
show
Documentation introduced by
$boolType is of type string, but the function expects a array|null.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
Bug introduced by
It seems like $key defined by parameter $key on line 273 can also be of type string; however, ONGR\ElasticsearchDSL\Se...tInterface::addToBool() does only seem to accept array|null, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
278
279
        return $this;
280
    }
281
282
    /**
283
     * Returns queries inside BoolFilter instance.
284
     *
285
     * @return BuilderInterface
286
     */
287
    public function getPostFilters()
288
    {
289
        $endpoint = $this->getEndpoint(PostFilterEndpoint::NAME);
290
291
        return $endpoint->getBool();
292
    }
293
294
    /**
295
     * Sets post filter endpoint parameters.
296
     *
297
     * @param array $parameters
298
     *
299
     * @return $this
300
     */
301
    public function setPostFilterParameters(array $parameters)
302
    {
303
        $this->setEndpointParameters(PostFilterEndpoint::NAME, $parameters);
304
305
        return $this;
306
    }
307
308
    /**
309
     * Adds aggregation into search.
310
     *
311
     * @param AbstractAggregation $aggregation
312
     *
313
     * @return $this
314
     */
315
    public function addAggregation(AbstractAggregation $aggregation)
316
    {
317
        $this->getEndpoint(AggregationsEndpoint::NAME)->add($aggregation, $aggregation->getName());
318
319
        return $this;
320
    }
321
322
    /**
323
     * Returns all aggregations.
324
     *
325
     * @return BuilderInterface[]
326
     */
327
    public function getAggregations()
328
    {
329
        return $this->getEndpoint(AggregationsEndpoint::NAME)->getAll();
330
    }
331
332
    /**
333
     * Adds sort to search.
334
     *
335
     * @param BuilderInterface $sort
336
     *
337
     * @return $this
338
     */
339
    public function addSort(BuilderInterface $sort)
340
    {
341
        $this->getEndpoint(SortEndpoint::NAME)->add($sort);
342
343
        return $this;
344
    }
345
346
    /**
347
     * Returns all set sorts.
348
     *
349
     * @return BuilderInterface[]
350
     */
351
    public function getSorts()
352
    {
353
        return $this->getEndpoint(SortEndpoint::NAME)->getAll();
354
    }
355
356
    /**
357
     * Allows to highlight search results on one or more fields.
358
     *
359
     * @param Highlight $highlight
360
     *
361
     * @return int Key of highlight.
362
     */
363
    public function addHighlight($highlight)
364
    {
365
        $this->getEndpoint(HighlightEndpoint::NAME)->add($highlight);
366
367
        return $this;
368
    }
369
370
    /**
371
     * Returns highlight builder.
372
     *
373
     * @return BuilderInterface
374
     */
375
    public function getHighlight()
376
    {
377
        /** @var HighlightEndpoint $highlightEndpoint */
378
        $highlightEndpoint = $this->getEndpoint(HighlightEndpoint::NAME);
379
380
        return $highlightEndpoint->getHighlight();
381
    }
382
383
    /**
384
    * Adds suggest into search.
385
    *
386
    * @param Suggest $suggest
387
    *
388
    * @return $this
389
    */
390
    public function addSuggest(Suggest $suggest)
391
    {
392
        $this->getEndpoint(SuggestEndpoint::NAME)->add($suggest, $suggest->getName());
0 ignored issues
show
Documentation introduced by
$suggest->getName() is of type string, but the function expects a array|null.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
393
394
        return $this;
395
    }
396
397
    /**
398
    * Returns all suggests.
399
    *
400
    * @return BuilderInterface[]
401
    */
402
    public function getSuggests()
403
    {
404
        return $this->getEndpoint(SuggestEndpoint::NAME)->getAll();
405
    }
406
407
    /**
408
     * Exclude documents which have a _score less than the minimum specified.
409
     *
410
     * @param float $minScore
411
     *
412
     * @return $this
413
     */
414
    public function setMinScore($minScore)
415
    {
416
        $this->minScore = $minScore;
417
418
        return $this;
419
    }
420
421
    /**
422
     * Returns min score value.
423
     *
424
     * @return float
425
     */
426
    public function getMinScore()
427
    {
428
        return $this->minScore;
429
    }
430
431
    /**
432
     * Paginate reed removed lts from.
433
     *
434
     * @param int $from
435
     *
436
     * @return $this
437
     */
438
    public function setFrom($from)
439
    {
440
        $this->from = $from;
441
442
        return $this;
443
    }
444
445
    /**
446
     * Sets timeout for query execution.
447
     *
448
     * @param $timeout
449
     *
450
     * @return $this
451
     */
452
    public function setTimeout($timeout)
453
    {
454
        $this->timeout = $timeout;
455
456
        return $this;
457
    }
458
459
    /**
460
     * Sets maximum number of documents per shard.
461
     *
462
     * @param $terminateAfter
463
     *
464
     * @return $this
465
     */
466
    public function setTerminateAfter($terminateAfter)
467
    {
468
        $this->terminateAfter = $terminateAfter;
469
470
        return $this;
471
    }
472
473
    /**
474
     * Returns results offset value.
475
     *
476
     * @return int
477
     */
478
    public function getFrom()
479
    {
480
        return $this->from;
481
    }
482
483
    /**
484
     * Set maximum number of results.
485
     *
486
     * @param int $size
487
     *
488
     * @return $this
489
     */
490
    public function setSize($size)
491
    {
492
        $this->size = $size;
493
494
        return $this;
495
    }
496
497
    /**
498
     * Returns maximum number of results query can request.
499
     *
500
     * @return int
501
     */
502
    public function getSize()
503
    {
504
        return $this->size;
505
    }
506
507
    /**
508
     * Allows to control how the _source field is returned with every hit.
509
     *
510
     * @param array|bool|string $source
511
     *
512
     * @return $this
513
     */
514
    public function setSource($source)
515
    {
516
        $this->source = $source;
517
518
        return $this;
519
    }
520
521
    /**
522
     * Returns source value.
523
     *
524
     * @return array|bool|string
525
     */
526
    public function getSource()
527
    {
528
        return $this->source;
529
    }
530
531
    /**
532
     * Allows to selectively load specific stored fields for each document represented by a search hit.
533
     *
534
     * @param array $fields
535
     *
536
     * @return $this
537
     */
538
    public function setFields(array $fields)
539
    {
540
        $this->fields = $fields;
541
542
        return $this;
543
    }
544
545
    /**
546
     * Returns field value.
547
     *
548
     * @return array
549
     */
550
    public function getFields()
551
    {
552
        return $this->fields;
553
    }
554
555
    /**
556
     * Allows to return a script evaluation (based on different fields) for each hit.
557
     *
558
     * @param array $scriptFields
559
     *
560
     * @return $this
561
     */
562
    public function setScriptFields($scriptFields)
563
    {
564
        $this->scriptFields = $scriptFields;
565
566
        return $this;
567
    }
568
569
    /**
570
     * Returns containing script fields.
571
     *
572
     * @return array
573
     */
574
    public function getScriptFields()
575
    {
576
        return $this->scriptFields;
577
    }
578
579
    /**
580
     * Sets explain property in request body search.
581
     *
582
     * @param bool $explain
583
     *
584
     * @return $this
585
     */
586
    public function setExplain($explain)
587
    {
588
        $this->explain = $explain;
589
590
        return $this;
591
    }
592
593
    /**
594
     * Returns if explain property is set in request body search.
595
     *
596
     * @return bool
597
     */
598
    public function isExplain()
599
    {
600
        return $this->explain;
601
    }
602
603
    /**
604
     * Sets a stats group.
605
     *
606
     * @param array $stats
607
     *
608
     * @return $this
609
     */
610
    public function setStats($stats)
611
    {
612
        $this->stats = $stats;
613
614
        return $this;
615
    }
616
617
    /**
618
     * Returns a stats group.
619
     *
620
     * @return array
621
     */
622
    public function getStats()
623
    {
624
        return $this->stats;
625
    }
626
627
    /**
628
     * Setter for scroll duration, effectively setting if search is scrolled or not.
629
     *
630
     * @param string|null $duration
631
     *
632
     * @return $this
633
     */
634
    public function setScroll($duration = '5m')
635
    {
636
        $this->scroll = $duration;
637
638
        return $this;
639
    }
640
641
    /**
642
     * Returns scroll duration.
643
     *
644
     * @return string|null
645
     */
646
    public function getScroll()
647
    {
648
        return $this->scroll;
649
    }
650
651
    /**
652
     * Set search type.
653
     *
654
     * @param string $searchType
655
     *
656
     * @return $this
657
     */
658
    public function setSearchType($searchType)
659
    {
660
        $this->searchType = $searchType;
661
662
        return $this;
663
    }
664
665
    /**
666
     * Returns search type used.
667
     *
668
     * @return string
669
     */
670
    public function getSearchType()
671
    {
672
        return $this->searchType;
673
    }
674
675
676
    /**
677
     * Set request cache.
678
     *
679
     * @param string $requestCache
680
     *
681
     * @return $this
682
     */
683
    public function setRequestCache($requestCache)
684
    {
685
        $this->requestCache = $requestCache;
686
687
        return $this;
688
    }
689
690
    /**
691
     * Returns request cache.
692
     *
693
     * @return string
694
     */
695
    public function getRequestCache()
696
    {
697
        return $this->requestCache;
698
    }
699
700
    /**
701
     * Setter for preference.
702
     *
703
     * Controls which shard replicas to execute the search request on.
704
     *
705
     * @param mixed $preferenceParams Example values:
706
     *                                _primary
707
     *                                _primary_first
708
     *                                _local
709
     *                                _only_node:xyz (xyz - node id)
710
     *                                _prefer_node:xyz (xyz - node id)
711
     *                                _shards:2,3 (2 and 3 specified shards)
712
     *                                custom value
713
     *                                string[] combination of params.
714
     *
715
     * @return $this
716
     */
717
    public function setPreference($preferenceParams)
718
    {
719
        if (is_string($preferenceParams)) {
720
            $this->preference[] = $preferenceParams;
721
        }
722
723
        if (is_array($preferenceParams) && !empty($preferenceParams)) {
724
            $this->preference = $preferenceParams;
725
        }
726
727
        return $this;
728
    }
729
730
    /**
731
     * Returns preference params as string.
732
     *
733
     * @return string
734
     */
735
    public function getPreference()
736
    {
737
        return $this->preference ? implode(';', $this->preference) : null;
738
    }
739
740
    /**
741
     * Returns query url parameters.
742
     *
743
     * @return array
744
     */
745
    public function getQueryParams()
746
    {
747
        return array_filter(
748
            [
749
                'scroll' => $this->getScroll(),
750
                'search_type' => $this->getSearchType(),
751
                'request_cache' => $this->getRequestCache(),
752
                'preference' => $this->getPreference(),
753
            ]
754
        );
755
    }
756
757
    /**
758
     * {@inheritdoc}
759
     */
760
    public function toArray()
761
    {
762
        $output = array_filter($this->serializer->normalize($this->endpoints));
0 ignored issues
show
Documentation introduced by
$this->endpoints is of type array<integer,object<ONG...archEndpointInterface>>, but the function expects a object.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
763
764
        $params = [
765
            'from' => 'from',
766
            'size' => 'size',
767
            'fields' => 'fields',
768
            'scriptFields' => 'script_fields',
769
            'explain' => 'explain',
770
            'stats' => 'stats',
771
            'minScore' => 'min_score',
772
            'source' => '_source',
773
            'timeout' => 'timeout',
774
            'terminateAfter' => 'terminate_after',
775
        ];
776
777
        foreach ($params as $field => $param) {
778
            if ($this->$field !== null) {
779
                $output[$param] = $this->$field;
780
            }
781
        }
782
783
        return $output;
784
    }
785
}
786