1<?php
2
3namespace Elastica\Query;
4
5use Elastica\Script\AbstractScript;
6use Elastica\Script\ScriptFields;
7
8/**
9 * Nested query.
10 *
11 * @author Guillaume Affringue <wamania@yahoo.fr>
12 *
13 * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-inner-hits.html
14 */
15class InnerHits extends AbstractQuery
16{
17    /**
18     * {@inheritdoc}
19     */
20    public function toArray()
21    {
22        $array = parent::toArray();
23
24        // if there are no params, it's ok, but ES will throw exception if json
25        // will be like {"top_hits":[]} instead of {"top_hits":{}}
26        if (empty($array['inner_hits'])) {
27            $array['inner_hits'] = new \stdClass();
28        }
29
30        return $array['inner_hits'];
31    }
32
33    /**
34     * The name to be used for the particular inner hit definition in the response.
35     * Useful when multiple inner hits have been defined in a single search request.
36     *
37     * @return $this
38     */
39    public function setName(string $name): self
40    {
41        return $this->setParam('name', $name);
42    }
43
44    /**
45     * The maximum number of inner matching hits to return per bucket. By default the top three matching hits are returned.
46     *
47     * @return $this
48     */
49    public function setSize(int $size = 3): self
50    {
51        return $this->setParam('size', $size);
52    }
53
54    /**
55     * The offset from the first result you want to fetch.
56     *
57     * @return $this
58     */
59    public function setFrom(int $from)
60    {
61        return $this->setParam('from', $from);
62    }
63
64    /**
65     * How the inner matching hits should be sorted. By default the hits are sorted by the score of the main query.
66     *
67     * @return $this
68     */
69    public function setSort(array $sortArgs): self
70    {
71        return $this->setParam('sort', $sortArgs);
72    }
73
74    /**
75     * Allows to control how the _source field is returned with every hit.
76     *
77     * @param array|bool $params Fields to be returned or false to disable source
78     *
79     * @return $this
80     */
81    public function setSource($params): self
82    {
83        return $this->setParam('_source', $params);
84    }
85
86    /**
87     * Returns a version for each search hit.
88     *
89     * @return $this
90     */
91    public function setVersion(bool $version): self
92    {
93        return $this->setParam('version', $version);
94    }
95
96    /**
97     * Enables explanation for each hit on how its score was computed.
98     *
99     * @return $this
100     */
101    public function setExplain(bool $explain): self
102    {
103        return $this->setParam('explain', $explain);
104    }
105
106    /**
107     * Set script fields.
108     *
109     * @return $this
110     */
111    public function setScriptFields(ScriptFields $scriptFields): self
112    {
113        return $this->setParam('script_fields', $scriptFields);
114    }
115
116    /**
117     * Adds a Script to the aggregation.
118     *
119     * @return $this
120     */
121    public function addScriptField(string $name, AbstractScript $script): self
122    {
123        if (!isset($this->_params['script_fields'])) {
124            $this->_params['script_fields'] = new ScriptFields();
125        }
126
127        $this->_params['script_fields']->addScript($name, $script);
128
129        return $this;
130    }
131
132    /**
133     * Sets highlight arguments for the results.
134     *
135     * @return $this
136     */
137    public function setHighlight(array $highlightArgs): self
138    {
139        return $this->setParam('highlight', $highlightArgs);
140    }
141
142    /**
143     * Allows to return the field data representation of a field for each hit.
144     *
145     * @return $this
146     */
147    public function setFieldDataFields(array $fields): self
148    {
149        return $this->setParam('docvalue_fields', $fields);
150    }
151}
152