Completed
Push — master ( 61efdf...7a2c62 )
by Simonas
01:38
created

src/Search.php (1 issue)

Labels
Severity

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
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\InnerHit\NestedInnerHit;
17
use ONGR\ElasticsearchDSL\Query\Compound\BoolQuery;
18
use ONGR\ElasticsearchDSL\SearchEndpoint\AbstractSearchEndpoint;
19
use ONGR\ElasticsearchDSL\SearchEndpoint\AggregationsEndpoint;
20
use ONGR\ElasticsearchDSL\SearchEndpoint\HighlightEndpoint;
21
use ONGR\ElasticsearchDSL\SearchEndpoint\InnerHitsEndpoint;
22
use ONGR\ElasticsearchDSL\SearchEndpoint\PostFilterEndpoint;
23
use ONGR\ElasticsearchDSL\SearchEndpoint\QueryEndpoint;
24
use ONGR\ElasticsearchDSL\SearchEndpoint\SearchEndpointFactory;
25
use ONGR\ElasticsearchDSL\SearchEndpoint\SearchEndpointInterface;
26
use ONGR\ElasticsearchDSL\SearchEndpoint\SortEndpoint;
27
use ONGR\ElasticsearchDSL\Serializer\Normalizer\CustomReferencedNormalizer;
28
use ONGR\ElasticsearchDSL\Serializer\OrderedSerializer;
29
use Symfony\Component\Serializer\Normalizer\CustomNormalizer;
30
use ONGR\ElasticsearchDSL\SearchEndpoint\SuggestEndpoint;
31
32
/**
33
 * Search object that can be executed by a manager.
34
 */
35
class Search
36
{
37
    /**
38
     * To retrieve hits from a certain offset. Defaults to 0.
39
     *
40
     * @var int
41
     */
42
    private $from;
43
44
    /**
45
     * The number of hits to return. Defaults to 10. If you do not care about getting some
46
     * hits back but only about the number of matches and/or aggregations, setting the value
47
     * to 0 will help performance.
48
     *
49
     * @var int
50
     */
51
    private $size;
52
53
    /**
54
     * Allows to control how the _source field is returned with every hit. By default
55
     * operations return the contents of the _source field unless you have used the
56
     * stored_fields parameter or if the _source field is disabled.
57
     *
58
     * @var bool
59
     */
60
    private $source;
61
62
    /**
63
     * Allows to selectively load specific stored fields for each document represented by a search hit.
64
     *
65
     * @var array
66
     */
67
    private $storedFields;
68
69
    /**
70
     * Allows to return a script evaluation (based on different fields) for each hit.
71
     * Script fields can work on fields that are not stored, and allow to return custom
72
     * values to be returned (the evaluated value of the script). Script fields can
73
     * also access the actual _source document indexed and extract specific elements
74
     * to be returned from it (can be an "object" type).
75
     *
76
     * @var array
77
     */
78
    private $scriptFields;
79
80
    /**
81
     * Allows to return the doc value representation of a field for each hit. Doc value
82
     * fields can work on fields that are not stored. Note that if the fields parameter
83
     * specifies fields without docvalues it will try to load the value from the fielddata
84
     * cache causing the terms for that field to be loaded to memory (cached), which will
85
     * result in more memory consumption.
86
     *
87
     * @var array
88
     */
89
    private $docValueFields;
90
91
    /**
92
     * Enables explanation for each hit on how its score was computed.
93
     *
94
     * @var bool
95
     */
96
    private $explain;
97
98
    /**
99
     * Returns a version for each search hit.
100
     *
101
     * @var bool
102
     */
103
    private $version;
104
105
    /**
106
     * Allows to configure different boost level per index when searching across more
107
     * than one indices. This is very handy when hits coming from one index matter more
108
     * than hits coming from another index (think social graph where each user has an index).
109
     *
110
     * @var array
111
     */
112
    private $indicesBoost;
113
114
    /**
115
     * Exclude documents which have a _score less than the minimum specified in min_score.
116
     *
117
     * @var int
118
     */
119
    private $minScore;
120
121
    /**
122
     * Pagination of results can be done by using the from and size but the cost becomes
123
     * prohibitive when the deep pagination is reached. The index.max_result_window which
124
     * defaults to 10,000 is a safeguard, search requests take heap memory and time
125
     * proportional to from + size. The Scroll api is recommended for efficient deep
126
     * scrolling but scroll contexts are costly and it is not recommended to use it for
127
     * real time user requests. The search_after parameter circumvents this problem by
128
     * providing a live cursor. The idea is to use the results from the previous page to
129
     * help the retrieval of the next page.
130
     *
131
     * @var array
132
     */
133
    private $searchAfter;
134
135
    /**
136
     * URI parameters alongside Request body search.
137
     *
138
     * @link https://www.elastic.co/guide/en/elasticsearch/reference/current/search-uri-request.html
139
     *
140
     * @var array
141
     */
142
    private $uriParams = [];
143
144
    /**
145
     * While a search request returns a single “page” of results, the scroll API can be used to retrieve
146
     * large numbers of results (or even all results) from a single search request, in much the same way
147
     * as you would use a cursor on a traditional database. Scrolling is not intended for real time user
148
     * requests, but rather for processing large amounts of data, e.g. in order to reindex the contents
149
     * of one index into a new index with a different configuration.
150
     *
151
     * @var string
152
     */
153
    private $scroll;
154
155
    /**
156
     * @var OrderedSerializer
157
     */
158
    private static $serializer;
159
160
    /**
161
     * @var SearchEndpointInterface[]
162
     */
163
    private $endpoints = [];
164
165
    /**
166
     * Initializes serializer.
167
     */
168
    public function __construct()
169
    {
170
        if (static::$serializer === null) {
171
            static::$serializer = new OrderedSerializer(
172
                [
173
                    new CustomReferencedNormalizer(),
174
                    new CustomNormalizer(),
175
                ]
176
            );
177
        }
178
    }
179
180
    /**
181
     * Destroys search endpoint.
182
     *
183
     * @param string $type Endpoint type.
184
     */
185
    public function destroyEndpoint($type)
186
    {
187
        unset($this->endpoints[$type]);
188
    }
189
190
    /**
191
     * Adds query to the search.
192
     *
193
     * @param BuilderInterface $query
194
     * @param string           $boolType
195
     * @param string           $key
196
     *
197
     * @return $this
198
     */
199
    public function addQuery(BuilderInterface $query, $boolType = BoolQuery::MUST, $key = null)
200
    {
201
        $endpoint = $this->getEndpoint(QueryEndpoint::NAME);
202
        $endpoint->addToBool($query, $boolType, $key);
203
204
        return $this;
205
    }
206
207
    /**
208
     * Returns endpoint instance.
209
     *
210
     * @param string $type Endpoint type.
211
     *
212
     * @return SearchEndpointInterface
213
     */
214
    private function getEndpoint($type)
215
    {
216
        if (!array_key_exists($type, $this->endpoints)) {
217
            $this->endpoints[$type] = SearchEndpointFactory::get($type);
218
        }
219
220
        return $this->endpoints[$type];
221
    }
222
223
    /**
224
     * Returns queries inside BoolQuery instance.
225
     *
226
     * @return BuilderInterface
227
     */
228
    public function getQueries()
229
    {
230
        $endpoint = $this->getEndpoint(QueryEndpoint::NAME);
231
232
        return $endpoint->getBool();
233
    }
234
235
    /**
236
     * Sets query endpoint parameters.
237
     *
238
     * @param array $parameters
239
     *
240
     * @return $this
241
     */
242
    public function setQueryParameters(array $parameters)
243
    {
244
        $this->setEndpointParameters(QueryEndpoint::NAME, $parameters);
245
246
        return $this;
247
    }
248
249
    /**
250
     * Sets parameters to the endpoint.
251
     *
252
     * @param string $endpointName
253
     * @param array  $parameters
254
     */
255
    public function setEndpointParameters($endpointName, array $parameters)
256
    {
257
        /** @var AbstractSearchEndpoint $endpoint */
258
        $endpoint = $this->getEndpoint($endpointName);
259
        $endpoint->setParameters($parameters);
260
    }
261
262
    /**
263
     * Adds a post filter to search.
264
     *
265
     * @param BuilderInterface $filter   Filter.
266
     * @param string           $boolType Example boolType values:
267
     *                                   - must
268
     *                                   - must_not
269
     *                                   - should.
270
     * @param string           $key
271
     *
272
     * @return $this.
273
     */
274
    public function addPostFilter(BuilderInterface $filter, $boolType = BoolQuery::MUST, $key = null)
275
    {
276
        $this
277
            ->getEndpoint(PostFilterEndpoint::NAME)
278
            ->addToBool($filter, $boolType, $key);
279
280
        return $this;
281
    }
282
283
    /**
284
     * Returns queries inside BoolFilter instance.
285
     *
286
     * @return BuilderInterface
287
     */
288
    public function getPostFilters()
289
    {
290
        $endpoint = $this->getEndpoint(PostFilterEndpoint::NAME);
291
292
        return $endpoint->getBool();
293
    }
294
295
    /**
296
     * Sets post filter endpoint parameters.
297
     *
298
     * @param array $parameters
299
     *
300
     * @return $this
301
     */
302
    public function setPostFilterParameters(array $parameters)
303
    {
304
        $this->setEndpointParameters(PostFilterEndpoint::NAME, $parameters);
305
306
        return $this;
307
    }
308
309
    /**
310
     * Adds aggregation into search.
311
     *
312
     * @param AbstractAggregation $aggregation
313
     *
314
     * @return $this
315
     */
316
    public function addAggregation(AbstractAggregation $aggregation)
317
    {
318
        $this->getEndpoint(AggregationsEndpoint::NAME)->add($aggregation, $aggregation->getName());
319
320
        return $this;
321
    }
322
323
    /**
324
     * Returns all aggregations.
325
     *
326
     * @return BuilderInterface[]
327
     */
328
    public function getAggregations()
329
    {
330
        return $this->getEndpoint(AggregationsEndpoint::NAME)->getAll();
331
    }
332
333
    /**
334
     * Adds inner hit into search.
335
     *
336
     * @param NestedInnerHit $innerHit
337
     *
338
     * @return $this
339
     */
340
    public function addInnerHit(NestedInnerHit $innerHit)
341
    {
342
        $this->getEndpoint(InnerHitsEndpoint::NAME)->add($innerHit, $innerHit->getName());
343
344
        return $this;
345
    }
346
347
    /**
348
     * Returns all inner hits.
349
     *
350
     * @return BuilderInterface[]
351
     */
352
    public function getInnerHits()
353
    {
354
        return $this->getEndpoint(InnerHitsEndpoint::NAME)->getAll();
355
    }
356
357
    /**
358
     * Adds sort to search.
359
     *
360
     * @param BuilderInterface $sort
361
     *
362
     * @return $this
363
     */
364
    public function addSort(BuilderInterface $sort)
365
    {
366
        $this->getEndpoint(SortEndpoint::NAME)->add($sort);
367
368
        return $this;
369
    }
370
371
    /**
372
     * Returns all set sorts.
373
     *
374
     * @return BuilderInterface[]
375
     */
376
    public function getSorts()
377
    {
378
        return $this->getEndpoint(SortEndpoint::NAME)->getAll();
379
    }
380
381
    /**
382
     * Allows to highlight search results on one or more fields.
383
     *
384
     * @param Highlight $highlight
385
     *
386
     * @return $this.
387
     */
388
    public function addHighlight($highlight)
389
    {
390
        $this->getEndpoint(HighlightEndpoint::NAME)->add($highlight);
391
392
        return $this;
393
    }
394
395
    /**
396
     * Returns highlight builder.
397
     *
398
     * @return BuilderInterface
399
     */
400
    public function getHighlights()
401
    {
402
        /** @var HighlightEndpoint $highlightEndpoint */
403
        $highlightEndpoint = $this->getEndpoint(HighlightEndpoint::NAME);
404
405
        return $highlightEndpoint->getHighlight();
406
    }
407
408
    /**
409
    * Adds suggest into search.
410
    *
411
    * @param BuilderInterface $suggest
412
    *
413
    * @return $this
414
    */
415
    public function addSuggest(BuilderInterface $suggest)
416
    {
417
        $this->getEndpoint(SuggestEndpoint::NAME)->add($suggest, $suggest->getName());
0 ignored issues
show
It seems like you code against a concrete implementation and not the interface ONGR\ElasticsearchDSL\BuilderInterface as the method getName() does only exist in the following implementations of said interface: ONGR\ElasticsearchDSL\Ag...ion\AbstractAggregation, ONGR\ElasticsearchDSL\Ag...acencyMatrixAggregation, ONGR\ElasticsearchDSL\Ag...ateHistogramAggregation, ONGR\ElasticsearchDSL\Ag...ing\ChildrenAggregation, ONGR\ElasticsearchDSL\Ag...ng\CompositeAggregation, ONGR\ElasticsearchDSL\Ag...ateHistogramAggregation, ONGR\ElasticsearchDSL\Ag...ng\DateRangeAggregation, ONGR\ElasticsearchDSL\Ag...ifiedSamplerAggregation, ONGR\ElasticsearchDSL\Ag...eting\FilterAggregation, ONGR\ElasticsearchDSL\Ag...ting\FiltersAggregation, ONGR\ElasticsearchDSL\Ag...\GeoDistanceAggregation, ONGR\ElasticsearchDSL\Ag...\GeoHashGridAggregation, ONGR\ElasticsearchDSL\Ag...eting\GlobalAggregation, ONGR\ElasticsearchDSL\Ag...ng\HistogramAggregation, ONGR\ElasticsearchDSL\Ag...ng\Ipv4RangeAggregation, ONGR\ElasticsearchDSL\Ag...ting\MissingAggregation, ONGR\ElasticsearchDSL\Ag...eting\NestedAggregation, ONGR\ElasticsearchDSL\Ag...keting\RangeAggregation, ONGR\ElasticsearchDSL\Ag...everseNestedAggregation, ONGR\ElasticsearchDSL\Ag...ting\SamplerAggregation, ONGR\ElasticsearchDSL\Ag...ificantTermsAggregation, ONGR\ElasticsearchDSL\Ag...nificantTextAggregation, ONGR\ElasticsearchDSL\Ag...keting\TermsAggregation, ONGR\ElasticsearchDSL\Ag...n\Matrix\MaxAggregation, ONGR\ElasticsearchDSL\Ag...n\Metric\AvgAggregation, ONGR\ElasticsearchDSL\Ag...\CardinalityAggregation, ONGR\ElasticsearchDSL\Ag...xtendedStatsAggregation, ONGR\ElasticsearchDSL\Ag...ic\GeoBoundsAggregation, ONGR\ElasticsearchDSL\Ag...\GeoCentroidAggregation, ONGR\ElasticsearchDSL\Ag...n\Metric\MaxAggregation, ONGR\ElasticsearchDSL\Ag...n\Metric\MinAggregation, ONGR\ElasticsearchDSL\Ag...centileRanksAggregation, ONGR\ElasticsearchDSL\Ag...\PercentilesAggregation, ONGR\ElasticsearchDSL\Ag...riptedMetricAggregation, ONGR\ElasticsearchDSL\Ag...Metric\StatsAggregation, ONGR\ElasticsearchDSL\Ag...n\Metric\SumAggregation, ONGR\ElasticsearchDSL\Ag...tric\TopHitsAggregation, ONGR\ElasticsearchDSL\Ag...c\ValueCountAggregation, ONGR\ElasticsearchDSL\Ag...ractPipelineAggregation, ONGR\ElasticsearchDSL\Ag...ne\AvgBucketAggregation, ONGR\ElasticsearchDSL\Ag...BucketScriptAggregation, ONGR\ElasticsearchDSL\Ag...cketSelectorAggregation, ONGR\ElasticsearchDSL\Ag...e\BucketSortAggregation, ONGR\ElasticsearchDSL\Ag...umulativeSumAggregation, ONGR\ElasticsearchDSL\Ag...e\DerivativeAggregation, ONGR\ElasticsearchDSL\Ag...dStatsBucketAggregation, ONGR\ElasticsearchDSL\Ag...ne\MaxBucketAggregation, ONGR\ElasticsearchDSL\Ag...ne\MinBucketAggregation, ONGR\ElasticsearchDSL\Ag...ovingAverageAggregation, ONGR\ElasticsearchDSL\Ag...vingFunctionAggregation, ONGR\ElasticsearchDSL\Ag...ntilesBucketAggregation, ONGR\ElasticsearchDSL\Ag...DifferencingAggregation, ONGR\ElasticsearchDSL\Ag...\StatsBucketAggregation, ONGR\ElasticsearchDSL\Ag...ne\SumBucketAggregation, ONGR\ElasticsearchDSL\InnerHit\NestedInnerHit, ONGR\ElasticsearchDSL\InnerHit\ParentInnerHit, ONGR\ElasticsearchDSL\Suggest\Suggest.

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...
418
419
        return $this;
420
    }
421
422
    /**
423
    * Returns all suggests.
424
    *
425
    * @return BuilderInterface[]
426
    */
427
    public function getSuggests()
428
    {
429
        return $this->getEndpoint(SuggestEndpoint::NAME)->getAll();
430
    }
431
432
    /**
433
     * @return int
434
     */
435
    public function getFrom()
436
    {
437
        return $this->from;
438
    }
439
440
    /**
441
     * @param int $from
442
     * @return $this
443
     */
444
    public function setFrom($from)
445
    {
446
        $this->from = $from;
447
        return $this;
448
    }
449
450
    /**
451
     * @return int
452
     */
453
    public function getSize()
454
    {
455
        return $this->size;
456
    }
457
458
    /**
459
     * @param int $size
460
     * @return $this
461
     */
462
    public function setSize($size)
463
    {
464
        $this->size = $size;
465
        return $this;
466
    }
467
468
    /**
469
     * @return bool
470
     */
471
    public function isSource()
472
    {
473
        return $this->source;
474
    }
475
476
    /**
477
     * @param bool $source
478
     * @return $this
479
     */
480
    public function setSource($source)
481
    {
482
        $this->source = $source;
483
        return $this;
484
    }
485
486
    /**
487
     * @return array
488
     */
489
    public function getStoredFields()
490
    {
491
        return $this->storedFields;
492
    }
493
494
    /**
495
     * @param array $storedFields
496
     * @return $this
497
     */
498
    public function setStoredFields($storedFields)
499
    {
500
        $this->storedFields = $storedFields;
501
        return $this;
502
    }
503
504
    /**
505
     * @return array
506
     */
507
    public function getScriptFields()
508
    {
509
        return $this->scriptFields;
510
    }
511
512
    /**
513
     * @param array $scriptFields
514
     * @return $this
515
     */
516
    public function setScriptFields($scriptFields)
517
    {
518
        $this->scriptFields = $scriptFields;
519
        return $this;
520
    }
521
522
    /**
523
     * @return array
524
     */
525
    public function getDocValueFields()
526
    {
527
        return $this->docValueFields;
528
    }
529
530
    /**
531
     * @param array $docValueFields
532
     * @return $this
533
     */
534
    public function setDocValueFields($docValueFields)
535
    {
536
        $this->docValueFields = $docValueFields;
537
        return $this;
538
    }
539
540
    /**
541
     * @return bool
542
     */
543
    public function isExplain()
544
    {
545
        return $this->explain;
546
    }
547
548
    /**
549
     * @param bool $explain
550
     * @return $this
551
     */
552
    public function setExplain($explain)
553
    {
554
        $this->explain = $explain;
555
        return $this;
556
    }
557
558
    /**
559
     * @return bool
560
     */
561
    public function isVersion()
562
    {
563
        return $this->version;
564
    }
565
566
    /**
567
     * @param bool $version
568
     * @return $this
569
     */
570
    public function setVersion($version)
571
    {
572
        $this->version = $version;
573
        return $this;
574
    }
575
576
    /**
577
     * @return array
578
     */
579
    public function getIndicesBoost()
580
    {
581
        return $this->indicesBoost;
582
    }
583
584
    /**
585
     * @param array $indicesBoost
586
     * @return $this
587
     */
588
    public function setIndicesBoost($indicesBoost)
589
    {
590
        $this->indicesBoost = $indicesBoost;
591
        return $this;
592
    }
593
594
    /**
595
     * @return int
596
     */
597
    public function getMinScore()
598
    {
599
        return $this->minScore;
600
    }
601
602
    /**
603
     * @param int $minScore
604
     * @return $this
605
     */
606
    public function setMinScore($minScore)
607
    {
608
        $this->minScore = $minScore;
609
        return $this;
610
    }
611
612
    /**
613
     * @return array
614
     */
615
    public function getSearchAfter()
616
    {
617
        return $this->searchAfter;
618
    }
619
620
    /**
621
     * @param array $searchAfter
622
     * @return $this
623
     */
624
    public function setSearchAfter($searchAfter)
625
    {
626
        $this->searchAfter = $searchAfter;
627
        return $this;
628
    }
629
630
    /**
631
     * @return string
632
     */
633
    public function getScroll()
634
    {
635
        return $this->scroll;
636
    }
637
638
    /**
639
     * @param string $scroll
640
     * @return $this
641
     */
642
    public function setScroll($scroll = '5m')
643
    {
644
        $this->scroll = $scroll;
645
646
        $this->addUriParam('scroll', $this->scroll);
647
648
        return $this;
649
    }
650
651
    /**
652
     * @param string $name
653
     * @param string|array|bool $value
654
     *
655
     * @return $this
656
     */
657
    public function addUriParam($name, $value)
658
    {
659
        if (in_array($name, [
660
            'q',
661
            'df',
662
            'analyzer',
663
            'analyze_wildcard',
664
            'default_operator',
665
            'lenient',
666
            'explain',
667
            '_source',
668
            '_source_exclude',
669
            '_source_include',
670
            'stored_fields',
671
            'sort',
672
            'track_scores',
673
            'timeout',
674
            'terminate_after',
675
            'from',
676
            'size',
677
            'search_type',
678
            'scroll',
679
            'allow_no_indices',
680
            'ignore_unavailable',
681
            'typed_keys',
682
            'pre_filter_shard_size',
683
            'ignore_unavailable',
684
        ])) {
685
            $this->uriParams[$name] = $value;
686
        } else {
687
            throw new \InvalidArgumentException(sprintf('Parameter %s is not supported.', $value));
688
        }
689
690
        return $this;
691
    }
692
693
    /**
694
     * Returns query url parameters.
695
     *
696
     * @return array
697
     */
698
    public function getUriParams()
699
    {
700
        return $this->uriParams;
701
    }
702
703
    /**
704
     * {@inheritdoc}
705
     */
706
    public function toArray()
707
    {
708
        $output = array_filter(static::$serializer->normalize($this->endpoints));
709
710
        $params = [
711
            'from' => 'from',
712
            'size' => 'size',
713
            'source' => '_source',
714
            'storedFields' => 'stored_fields',
715
            'scriptFields' => 'script_fields',
716
            'docValueFields' => 'docvalue_fields',
717
            'explain' => 'explain',
718
            'version' => 'version',
719
            'indicesBoost' => 'indices_boost',
720
            'minScore' => 'min_score',
721
            'searchAfter' => 'search_after',
722
        ];
723
724
        foreach ($params as $field => $param) {
725
            if ($this->$field !== null) {
726
                $output[$param] = $this->$field;
727
            }
728
        }
729
730
        return $output;
731
    }
732
}
733