1<?php
2
3namespace Elastica\Query;
4
5/**
6 * More Like This query.
7 *
8 * @author Raul Martinez, Jr <juneym@gmail.com>
9 *
10 * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-mlt-query.html
11 */
12class MoreLikeThis extends AbstractQuery
13{
14    /**
15     * Set fields to which to restrict the mlt query.
16     *
17     * @param array $fields Field names
18     *
19     * @return $this
20     */
21    public function setFields(array $fields): self
22    {
23        return $this->setParam('fields', $fields);
24    }
25
26    /**
27     * Set the "like" value.
28     *
29     * @param string|self $like
30     *
31     * @return $this
32     */
33    public function setLike($like): self
34    {
35        return $this->setParam('like', $like);
36    }
37
38    /**
39     * Set boost.
40     *
41     * @param float $boost Boost value
42     *
43     * @return $this
44     */
45    public function setBoost(float $boost = 1.0): self
46    {
47        return $this->setParam('boost', $boost);
48    }
49
50    /**
51     * Set max_query_terms.
52     *
53     * @param int $maxQueryTerms Max query terms value
54     *
55     * @return $this
56     */
57    public function setMaxQueryTerms(int $maxQueryTerms = 25): self
58    {
59        return $this->setParam('max_query_terms', $maxQueryTerms);
60    }
61
62    /**
63     * Set min term frequency.
64     *
65     * @param int $minTermFreq
66     *
67     * @return $this
68     */
69    public function setMinTermFrequency(int $minTermFreq = 2): self
70    {
71        return $this->setParam('min_term_freq', $minTermFreq);
72    }
73
74    /**
75     * set min document frequency.
76     *
77     * @param int $minDocFreq
78     *
79     * @return $this
80     */
81    public function setMinDocFrequency(int $minDocFreq = 5): self
82    {
83        return $this->setParam('min_doc_freq', $minDocFreq);
84    }
85
86    /**
87     * set max document frequency.
88     *
89     * @param int $maxDocFreq
90     *
91     * @return $this
92     */
93    public function setMaxDocFrequency(int $maxDocFreq = 0): self
94    {
95        return $this->setParam('max_doc_freq', $maxDocFreq);
96    }
97
98    /**
99     * Set min word length.
100     *
101     * @param int $minWordLength
102     *
103     * @return $this
104     */
105    public function setMinWordLength(int $minWordLength = 0): self
106    {
107        return $this->setParam('min_word_length', $minWordLength);
108    }
109
110    /**
111     * Set max word length.
112     *
113     * @param int $maxWordLength
114     *
115     * @return $this
116     */
117    public function setMaxWordLength(int $maxWordLength = 0): self
118    {
119        return $this->setParam('max_word_length', $maxWordLength);
120    }
121
122    /**
123     * Set boost terms.
124     *
125     * @param bool $boostTerms
126     *
127     * @return $this
128     */
129    public function setBoostTerms(bool $boostTerms = false): self
130    {
131        return $this->setParam('boost_terms', $boostTerms);
132    }
133
134    /**
135     * Set analyzer.
136     *
137     * @param string $analyzer
138     *
139     * @return $this
140     */
141    public function setAnalyzer(string $analyzer): self
142    {
143        $analyzer = \trim($analyzer);
144
145        return $this->setParam('analyzer', $analyzer);
146    }
147
148    /**
149     * Set stop words.
150     *
151     * @param array $stopWords
152     *
153     * @return $this
154     */
155    public function setStopWords(array $stopWords): self
156    {
157        return $this->setParam('stop_words', $stopWords);
158    }
159
160    /**
161     * Set minimum_should_match option.
162     *
163     * @param int|string $minimumShouldMatch
164     *
165     * @return $this
166     */
167    public function setMinimumShouldMatch($minimumShouldMatch = '30%'): self
168    {
169        return $this->setParam('minimum_should_match', $minimumShouldMatch);
170    }
171
172    /**
173     * {@inheritdoc}
174     */
175    public function toArray(): array
176    {
177        $array = parent::toArray();
178
179        // If _id is provided, perform MLT on an existing document from the index
180        // If _source is provided, perform MLT on a document provided as an input
181        if (!empty($array['more_like_this']['like']['_id'])) {
182            $doc = $array['more_like_this']['like'];
183            $doc = \array_intersect_key($doc, ['_index' => 1, '_type' => 1, '_id' => 1]);
184            $array['more_like_this']['like'] = $doc;
185        } elseif (!empty($array['more_like_this']['like']['_source'])) {
186            $doc = $array['more_like_this']['like'];
187            $doc['doc'] = $array['more_like_this']['like']['_source'];
188            unset($doc['_id']);
189            unset($doc['_source']);
190            $array['more_like_this']['like'] = $doc;
191        }
192
193        return $array;
194    }
195}
196