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