Completed
Push — v0.10 ( f42b97...309689 )
by Simonas
8s
created

Search   C

Complexity

Total Complexity 55

Size/Duplication

Total Lines 732
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Importance

Changes 3
Bugs 0 Features 0
Metric Value
wmc 55
c 3
b 0
f 0
lcom 1
cbo 5
dl 0
loc 732
rs 5

48 Methods

Rating   Name   Duplication   Size   Complexity  
A destroyFilters() 0 4 1
A getMinScore() 0 4 1
A getFrom() 0 4 1
A getSize() 0 4 1
A getSource() 0 4 1
A getFields() 0 4 1
A getScriptFields() 0 4 1
A isExplain() 0 4 1
A getStats() 0 4 1
A getScroll() 0 4 1
A getSearchType() 0 4 1
A getTimeout() 0 4 1
A setTimeout() 0 4 1
A setPreference() 0 12 4
A getPreference() 0 4 2
A destroyEndpoint() 0 4 1
A __construct() 0 9 1
A addQuery() 0 8 1
A setBoolQueryParameters() 0 8 1
A getQuery() 0 6 1
A destroyQuery() 0 6 1
A addFilter() 0 10 1
A getFilters() 0 6 1
A setBoolFilterParameters() 0 8 1
A addPostFilter() 0 8 1
A getPostFilters() 0 6 1
A setBoolPostFilterParameters() 0 8 1
A setMinScore() 0 6 1
A setFrom() 0 6 1
A setSize() 0 6 1
A addSort() 0 8 1
A getSorts() 0 6 1
A setSource() 0 6 1
A setFields() 0 6 1
A setScriptFields() 0 6 1
A setHighlight() 0 8 1
A getHighlight() 0 6 1
A setExplain() 0 6 1
A setStats() 0 6 1
A addAggregation() 0 8 1
A getAggregations() 0 6 1
A addSuggester() 0 8 1
A getSuggesters() 0 6 1
A setScroll() 0 6 1
A setSearchType() 0 6 1
A getQueryParams() 0 11 1
A toArray() 0 23 3
A getEndpoint() 0 8 2

How to fix   Complexity   

Complex Class

Complex classes like Search 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. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

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 Search, and based on these observations, apply Extract Interface, too.

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\ElasticsearchBundle\DSL;
13
14
use ONGR\ElasticsearchBundle\DSL\Aggregation\AbstractAggregation;
15
use ONGR\ElasticsearchBundle\DSL\Highlight\Highlight;
16
use ONGR\ElasticsearchBundle\DSL\SearchEndpoint\SearchEndpointFactory;
17
use ONGR\ElasticsearchBundle\DSL\SearchEndpoint\SearchEndpointInterface;
18
use ONGR\ElasticsearchBundle\DSL\Sort\AbstractSort;
19
use ONGR\ElasticsearchBundle\DSL\Sort\Sorts;
20
use ONGR\ElasticsearchBundle\DSL\Suggester\AbstractSuggester;
21
use ONGR\ElasticsearchBundle\Serializer\Normalizer\CustomReferencedNormalizer;
22
use ONGR\ElasticsearchBundle\Serializer\OrderedSerializer;
23
use Symfony\Component\Serializer\Normalizer\CustomNormalizer;
24
25
/**
26
 * Search object that can be executed by a manager.
27
 */
28
class Search
29
{
30
    /**
31
     * @var int
32
     */
33
    private $size;
34
35
    /**
36
     * @var int
37
     */
38
    private $from;
39
40
    /**
41
     * @var string|null
42
     */
43
    private $scroll;
44
45
    /**
46
     * @var array|bool|string
47
     */
48
    private $source;
49
50
    /**
51
     * @var array
52
     */
53
    private $fields;
54
55
    /**
56
     * @var array
57
     */
58
    private $scriptFields;
59
60
    /**
61
     * @var string
62
     */
63
    private $timeout;
64
65
    /**
66
     * @var string
67
     */
68
    private $searchType;
69
70
    /**
71
     * @var bool
72
     */
73
    private $explain;
74
75
    /**
76
     * @var array
77
     */
78
    private $stats;
79
80
    /**
81
     * @var string[]
82
     */
83
    private $preference;
84
85
    /**
86
     * @var float
87
     */
88
    private $minScore;
89
90
    /**
91
     * @var OrderedSerializer
92
     */
93
    private $serializer;
94
95
    /**
96
     * @var SearchEndpointInterface[]
97
     */
98
    private $endpoints = [];
99
100
    /**
101
     * Initializes serializer.
102
     */
103
    public function __construct()
104
    {
105
        $this->serializer = new OrderedSerializer(
106
            [
107
                new CustomReferencedNormalizer(),
108
                new CustomNormalizer(),
109
            ]
110
        );
111
    }
112
113
    /**
114
     * Adds query to search.
115
     *
116
     * @param BuilderInterface $query
117
     * @param string           $boolType
118
     *
119
     * @return Search
120
     */
121
    public function addQuery(BuilderInterface $query, $boolType = '')
122
    {
123
        $this
124
            ->getEndpoint('query')
125
            ->addBuilder($query, ['bool_type' => $boolType]);
126
127
        return $this;
128
    }
129
130
    /**
131
     * Sets parameters for bool query.
132
     *
133
     * @param array $params Example values:
134
     *                      - minimum_should_match => 1
135
     *                      - boost => 1.
136
     *
137
     * @return Search
138
     */
139
    public function setBoolQueryParameters(array $params)
140
    {
141
        $this
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface ONGR\ElasticsearchBundle...SearchEndpointInterface as the method setParameters() does only exist in the following implementations of said interface: ONGR\ElasticsearchBundle...\AbstractSearchEndpoint, ONGR\ElasticsearchBundle...Endpoint\FilterEndpoint, ONGR\ElasticsearchBundle...oint\PostFilterEndpoint, ONGR\ElasticsearchBundle...hEndpoint\QueryEndpoint.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
142
            ->getEndpoint('query')
143
            ->setParameters($params);
144
145
        return $this;
146
    }
147
148
    /**
149
     * Returns contained query.
150
     *
151
     * @return BuilderInterface
152
     */
153
    public function getQuery()
154
    {
155
        return $this
156
            ->getEndpoint('query')
157
            ->getBuilder();
158
    }
159
160
    /**
161
     * Destroys query part.
162
     *
163
     * @return Search
164
     */
165
    public function destroyQuery()
166
    {
167
        $this->destroyEndpoint('query');
168
169
        return $this;
170
    }
171
172
    /**
173
     * Adds a filter to search.
174
     *
175
     * @param BuilderInterface $filter   Filter.
176
     * @param string           $boolType Possible boolType values:
177
     *                                   - must
178
     *                                   - must_not
179
     *                                   - should.
180
     *
181
     * @return Search
182
     */
183
    public function addFilter(BuilderInterface $filter, $boolType = '')
184
    {
185
        $this->getEndpoint('query');
186
187
        $this
188
            ->getEndpoint('filter')
189
            ->addBuilder($filter, ['bool_type' => $boolType]);
190
191
        return $this;
192
    }
193
194
    /**
195
     * Returns currently contained filters.
196
     *
197
     * @return BuilderInterface
198
     */
199
    public function getFilters()
200
    {
201
        return $this
202
            ->getEndpoint('filter')
203
            ->getBuilder();
204
    }
205
206
    /**
207
     * Sets bool filter parameters.
208
     *
209
     * @param array $params Possible values:
210
     *                      _cache => true
211
     *                      false.
212
     *
213
     * @return Search
214
     */
215
    public function setBoolFilterParameters($params)
216
    {
217
        $this
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface ONGR\ElasticsearchBundle...SearchEndpointInterface as the method setParameters() does only exist in the following implementations of said interface: ONGR\ElasticsearchBundle...\AbstractSearchEndpoint, ONGR\ElasticsearchBundle...Endpoint\FilterEndpoint, ONGR\ElasticsearchBundle...oint\PostFilterEndpoint, ONGR\ElasticsearchBundle...hEndpoint\QueryEndpoint.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
218
            ->getEndpoint('filter')
219
            ->setParameters($params);
220
221
        return $this;
222
    }
223
224
    /**
225
     * Destroys filter part.
226
     */
227
    public function destroyFilters()
228
    {
229
        $this->destroyEndpoint('filter');
230
    }
231
232
    /**
233
     * Adds a post filter to search.
234
     *
235
     * @param BuilderInterface $postFilter Post filter.
236
     * @param string           $boolType   Possible boolType values:
237
     *                                     - must
238
     *                                     - must_not
239
     *                                     - should.
240
     *
241
     * @return Search
242
     */
243
    public function addPostFilter(BuilderInterface $postFilter, $boolType = '')
244
    {
245
        $this
246
            ->getEndpoint('post_filter')
247
            ->addBuilder($postFilter, ['bool_type' => $boolType]);
248
249
        return $this;
250
    }
251
252
    /**
253
     * Returns all contained post filters.
254
     *
255
     * @return BuilderInterface
256
     */
257
    public function getPostFilters()
258
    {
259
        return $this
260
            ->getEndpoint('post_filter')
261
            ->getBuilder();
262
    }
263
264
    /**
265
     * Sets bool post filter parameters.
266
     *
267
     * @param array $params Possible values:
268
     *                      _cache => true
269
     *                      false.
270
     *
271
     * @return Search
272
     */
273
    public function setBoolPostFilterParameters($params)
274
    {
275
        $this
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface ONGR\ElasticsearchBundle...SearchEndpointInterface as the method setParameters() does only exist in the following implementations of said interface: ONGR\ElasticsearchBundle...\AbstractSearchEndpoint, ONGR\ElasticsearchBundle...Endpoint\FilterEndpoint, ONGR\ElasticsearchBundle...oint\PostFilterEndpoint, ONGR\ElasticsearchBundle...hEndpoint\QueryEndpoint.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
276
            ->getEndpoint('post_filter')
277
            ->setParameters($params);
278
279
        return $this;
280
    }
281
282
    /**
283
     * Returns min score value.
284
     *
285
     * @return float
286
     */
287
    public function getMinScore()
288
    {
289
        return $this->minScore;
290
    }
291
292
    /**
293
     * Exclude documents which have a _score less than the minimum specified.
294
     *
295
     * @param float $minScore
296
     *
297
     * @return Search
298
     */
299
    public function setMinScore($minScore)
300
    {
301
        $this->minScore = $minScore;
302
303
        return $this;
304
    }
305
306
    /**
307
     * Paginate results from.
308
     *
309
     * @param int $from
310
     *
311
     * @return Search
312
     */
313
    public function setFrom($from)
314
    {
315
        $this->from = $from;
316
317
        return $this;
318
    }
319
320
    /**
321
     * Returns results offset value.
322
     *
323
     * @return int
324
     */
325
    public function getFrom()
326
    {
327
        return $this->from;
328
    }
329
330
    /**
331
     * Set maximum number of results.
332
     *
333
     * @param int $size
334
     *
335
     * @return Search
336
     */
337
    public function setSize($size)
338
    {
339
        $this->size = $size;
340
341
        return $this;
342
    }
343
344
    /**
345
     * Returns maximum number of results query can request.
346
     *
347
     * @return int
348
     */
349
    public function getSize()
350
    {
351
        return $this->size;
352
    }
353
354
    /**
355
     * Adds sort to search.
356
     *
357
     * @param AbstractSort $sort
358
     *
359
     * @return Search
360
     */
361
    public function addSort(AbstractSort $sort)
362
    {
363
        $this
364
            ->getEndpoint('sort')
365
            ->addBuilder($sort);
366
367
        return $this;
368
    }
369
370
    /**
371
     * Returns sorts object.
372
     *
373
     * @return Sorts
374
     */
375
    public function getSorts()
376
    {
377
        return $this
378
            ->getEndpoint('sort')
379
            ->getBuilder();
380
    }
381
382
    /**
383
     * Allows to control how the _source field is returned with every hit.
384
     *
385
     * @param array|bool|string $source
386
     *
387
     * @return Search
388
     */
389
    public function setSource($source)
390
    {
391
        $this->source = $source;
392
393
        return $this;
394
    }
395
396
    /**
397
     * Returns source value.
398
     *
399
     * @return array|bool|string
400
     */
401
    public function getSource()
402
    {
403
        return $this->source;
404
    }
405
406
    /**
407
     * Allows to selectively load specific stored fields for each document represented by a search hit.
408
     *
409
     * @param array $fields
410
     *
411
     * @return Search
412
     */
413
    public function setFields(array $fields)
414
    {
415
        $this->fields = $fields;
416
417
        return $this;
418
    }
419
420
    /**
421
     * Returns field value.
422
     *
423
     * @return array
424
     */
425
    public function getFields()
426
    {
427
        return $this->fields;
428
    }
429
430
    /**
431
     * Allows to return a script evaluation (based on different fields) for each hit.
432
     *
433
     * @param array $scriptFields
434
     *
435
     * @return Search
436
     */
437
    public function setScriptFields($scriptFields)
438
    {
439
        $this->scriptFields = $scriptFields;
440
441
        return $this;
442
    }
443
444
    /**
445
     * Returns containing script fields.
446
     *
447
     * @return array
448
     */
449
    public function getScriptFields()
450
    {
451
        return $this->scriptFields;
452
    }
453
454
    /**
455
     * Allows to highlight search results on one or more fields.
456
     *
457
     * @param Highlight $highlight
458
     *
459
     * @return Search
460
     */
461
    public function setHighlight($highlight)
462
    {
463
        $this
464
            ->getEndpoint('highlight')
465
            ->addBuilder($highlight);
466
467
        return $this;
468
    }
469
470
    /**
471
     * Returns containing highlight object.
472
     *
473
     * @return Highlight
474
     */
475
    public function getHighlight()
476
    {
477
        return $this
478
            ->getEndpoint('highlight')
479
            ->getBuilder();
480
    }
481
482
    /**
483
     * Sets explain property in request body search.
484
     *
485
     * @param bool $explain
486
     *
487
     * @return Search
488
     */
489
    public function setExplain($explain)
490
    {
491
        $this->explain = $explain;
492
493
        return $this;
494
    }
495
496
    /**
497
     * Returns if explain property is set in request body search.
498
     *
499
     * @return bool
500
     */
501
    public function isExplain()
502
    {
503
        return $this->explain;
504
    }
505
506
    /**
507
     * Sets a stats group.
508
     *
509
     * @param array $stats
510
     *
511
     * @return Search
512
     */
513
    public function setStats($stats)
514
    {
515
        $this->stats = $stats;
516
517
        return $this;
518
    }
519
520
    /**
521
     * Returns a stats group.
522
     *
523
     * @return array
524
     */
525
    public function getStats()
526
    {
527
        return $this->stats;
528
    }
529
530
    /**
531
     * Adds aggregation into search.
532
     *
533
     * @param AbstractAggregation $aggregation
534
     *
535
     * @return Search
536
     */
537
    public function addAggregation(AbstractAggregation $aggregation)
538
    {
539
        $this
540
            ->getEndpoint('aggregations')
541
            ->addBuilder($aggregation);
542
543
        return $this;
544
    }
545
546
    /**
547
     * Returns contained aggregations.
548
     *
549
     * @return AbstractAggregation[]
550
     */
551
    public function getAggregations()
552
    {
553
        return $this
554
            ->getEndpoint('aggregations')
555
            ->getBuilder();
556
    }
557
558
    /**
559
     * Adds suggester to search.
560
     *
561
     * @param AbstractSuggester $suggester
562
     *
563
     * @return Search
564
     */
565
    public function addSuggester(AbstractSuggester $suggester)
566
    {
567
        $this
568
            ->getEndpoint('suggest')
569
            ->addBuilder($suggester);
570
571
        return $this;
572
    }
573
574
    /**
575
     * Returns all contained suggester's.
576
     *
577
     * @return AbstractSuggester[]
578
     */
579
    public function getSuggesters()
580
    {
581
        return $this
582
            ->getEndpoint('suggest')
583
            ->getBuilder();
584
    }
585
586
    /**
587
     * Setter for scroll duration, effectively setting if search is scrolled or not.
588
     *
589
     * @param string|null $duration
590
     *
591
     * @return Search
592
     */
593
    public function setScroll($duration = '5m')
594
    {
595
        $this->scroll = $duration;
596
597
        return $this;
598
    }
599
600
    /**
601
     * Returns scroll duration.
602
     *
603
     * @return string|null
604
     */
605
    public function getScroll()
606
    {
607
        return $this->scroll;
608
    }
609
610
    /**
611
     * Set search type.
612
     *
613
     * @param string $searchType
614
     *
615
     * @return Search
616
     */
617
    public function setSearchType($searchType)
618
    {
619
        $this->searchType = $searchType;
620
621
        return $this;
622
    }
623
624
    /**
625
     * Returns search type used.
626
     *
627
     * @return string
628
     */
629
    public function getSearchType()
630
    {
631
        return $this->searchType;
632
    }
633
634
    /**
635
     * @return int
636
     */
637
    public function getTimeout()
638
    {
639
        return $this->timeout;
640
    }
641
642
    /**
643
     * @param int $timeout
644
     */
645
    public function setTimeout($timeout)
646
    {
647
        $this->timeout = $timeout;
0 ignored issues
show
Documentation Bug introduced by
The property $timeout was declared of type string, but $timeout is of type integer. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
648
    }
649
650
    /**
651
     * Setter for preference.
652
     *
653
     * Controls which shard replicas to execute the search request on.
654
     *
655
     * @param mixed $preferenceParams Possible values:
656
     *                                _primary
657
     *                                _primary_first
658
     *                                _local
659
     *                                _only_node:xyz (xyz - node id)
660
     *                                _prefer_node:xyz (xyz - node id)
661
     *                                _shards:2,3 (2 and 3 specified shards)
662
     *                                custom value
663
     *                                string[] combination of params.
664
     *
665
     * @return Search
666
     */
667
    public function setPreference($preferenceParams)
668
    {
669
        if (is_string($preferenceParams)) {
670
            $this->preference[] = $preferenceParams;
671
        }
672
673
        if (is_array($preferenceParams) && !empty($preferenceParams)) {
674
            $this->preference = $preferenceParams;
675
        }
676
677
        return $this;
678
    }
679
680
    /**
681
     * Returns preference params as string.
682
     *
683
     * @return string
684
     */
685
    public function getPreference()
686
    {
687
        return $this->preference ? implode(';', $this->preference) : null;
688
    }
689
690
    /**
691
     * Returns query url parameters.
692
     *
693
     * @return array
694
     */
695
    public function getQueryParams()
696
    {
697
        return array_filter(
698
            [
699
                'scroll' => $this->getScroll(),
700
                'timeout' => $this->getTimeout(),
701
                'search_type' => $this->getSearchType(),
702
                'preference' => $this->getPreference(),
703
            ]
704
        );
705
    }
706
707
    /**
708
     * {@inheritdoc}
709
     */
710
    public function toArray()
711
    {
712
        $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...
713
714
        $params = [
715
            'from' => 'from',
716
            'size' => 'size',
717
            'fields' => 'fields',
718
            'scriptFields' => 'script_fields',
719
            'explain' => 'explain',
720
            'stats' => 'stats',
721
            'minScore' => 'min_score',
722
            'source' => '_source',
723
        ];
724
725
        foreach ($params as $field => $param) {
726
            if ($this->$field !== null) {
727
                $output[$param] = $this->$field;
728
            }
729
        }
730
731
        return $output;
732
    }
733
734
    /**
735
     * Returns endpoint instance.
736
     *
737
     * @param string $type Endpoint type.
738
     *
739
     * @return SearchEndpointInterface
740
     */
741
    private function getEndpoint($type)
742
    {
743
        if (!array_key_exists($type, $this->endpoints)) {
744
            $this->endpoints[$type] = SearchEndpointFactory::get($type);
745
        }
746
747
        return $this->endpoints[$type];
748
    }
749
750
    /**
751
     * Destroys search endpoint.
752
     *
753
     * @param string $type Endpoint type.
754
     */
755
    private function destroyEndpoint($type)
756
    {
757
        unset($this->endpoints[$type]);
758
    }
759
}
760