Query.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429
  1. <?php
  2. namespace Elastica;
  3. use Elastica\Aggregation\AbstractAggregation;
  4. use Elastica\Exception\InvalidException;
  5. use Elastica\Query\AbstractQuery;
  6. use Elastica\Query\MatchAll;
  7. use Elastica\Query\QueryString;
  8. use Elastica\Script\AbstractScript;
  9. use Elastica\Script\ScriptFields;
  10. use Elastica\Suggest\AbstractSuggest;
  11. /**
  12. * Elastica query object.
  13. *
  14. * Creates different types of queries
  15. *
  16. * @author Nicolas Ruflin <spam@ruflin.com>
  17. *
  18. * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-body.html
  19. */
  20. class Query extends Param
  21. {
  22. /**
  23. * Suggest query or not.
  24. *
  25. * @var int Suggest
  26. */
  27. protected $_suggest = 0;
  28. /**
  29. * Creates a query object.
  30. *
  31. * @param array|\Elastica\Query\AbstractQuery $query OPTIONAL Query object (default = null)
  32. */
  33. public function __construct($query = null)
  34. {
  35. if (is_array($query)) {
  36. $this->setRawQuery($query);
  37. } elseif ($query instanceof AbstractQuery) {
  38. $this->setQuery($query);
  39. } elseif ($query instanceof Suggest) {
  40. $this->setSuggest($query);
  41. }
  42. }
  43. /**
  44. * Transforms the argument to a query object.
  45. *
  46. * For example, an empty argument will return a \Elastica\Query with a \Elastica\Query\MatchAll.
  47. *
  48. * @param mixed $query
  49. *
  50. * @throws InvalidException For an invalid argument
  51. *
  52. * @return self
  53. */
  54. public static function create($query)
  55. {
  56. switch (true) {
  57. case $query instanceof self:
  58. return $query;
  59. case $query instanceof AbstractQuery:
  60. return new self($query);
  61. case empty($query):
  62. return new self(new MatchAll());
  63. case is_array($query):
  64. return new self($query);
  65. case is_string($query):
  66. return new self(new QueryString($query));
  67. case $query instanceof AbstractSuggest:
  68. return new self(new Suggest($query));
  69. case $query instanceof Suggest:
  70. return new self($query);
  71. }
  72. throw new InvalidException('Unexpected argument to create a query for.');
  73. }
  74. /**
  75. * Sets query as raw array. Will overwrite all already set arguments.
  76. *
  77. * @param array $query Query array
  78. *
  79. * @return $this
  80. */
  81. public function setRawQuery(array $query)
  82. {
  83. $this->_params = $query;
  84. return $this;
  85. }
  86. /**
  87. * Sets the query.
  88. *
  89. * @param \Elastica\Query\AbstractQuery $query Query object
  90. *
  91. * @return $this
  92. */
  93. public function setQuery(AbstractQuery $query)
  94. {
  95. return $this->setParam('query', $query);
  96. }
  97. /**
  98. * Gets the query object.
  99. *
  100. * @return \Elastica\Query\AbstractQuery
  101. **/
  102. public function getQuery()
  103. {
  104. return $this->getParam('query');
  105. }
  106. /**
  107. * Sets the start from which the search results should be returned.
  108. *
  109. * @param int $from
  110. *
  111. * @return $this
  112. */
  113. public function setFrom($from)
  114. {
  115. return $this->setParam('from', $from);
  116. }
  117. /**
  118. * Sets sort arguments for the query
  119. * Replaces existing values.
  120. *
  121. * @param array $sortArgs Sorting arguments
  122. *
  123. * @return $this
  124. *
  125. * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-sort.html
  126. */
  127. public function setSort(array $sortArgs)
  128. {
  129. return $this->setParam('sort', $sortArgs);
  130. }
  131. /**
  132. * Adds a sort param to the query.
  133. *
  134. * @param mixed $sort Sort parameter
  135. *
  136. * @return $this
  137. *
  138. * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-sort.html
  139. */
  140. public function addSort($sort)
  141. {
  142. return $this->addParam('sort', $sort);
  143. }
  144. /**
  145. * Keep track of the scores when sorting results.
  146. *
  147. * @param bool $trackScores
  148. *
  149. * @return $this
  150. *
  151. * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-sort.html#_track_scores
  152. */
  153. public function setTrackScores($trackScores = true)
  154. {
  155. return $this->setParam('track_scores', (bool) $trackScores);
  156. }
  157. /**
  158. * Sets highlight arguments for the query.
  159. *
  160. * @param array $highlightArgs Set all highlight arguments
  161. *
  162. * @return $this
  163. *
  164. * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-highlighting.html
  165. */
  166. public function setHighlight(array $highlightArgs)
  167. {
  168. return $this->setParam('highlight', $highlightArgs);
  169. }
  170. /**
  171. * Adds a highlight argument.
  172. *
  173. * @param mixed $highlight Add highlight argument
  174. *
  175. * @return $this
  176. *
  177. * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-highlighting.html
  178. */
  179. public function addHighlight($highlight)
  180. {
  181. return $this->addParam('highlight', $highlight);
  182. }
  183. /**
  184. * Sets maximum number of results for this query.
  185. *
  186. * @param int $size OPTIONAL Maximal number of results for query (default = 10)
  187. *
  188. * @return $this
  189. */
  190. public function setSize($size = 10)
  191. {
  192. return $this->setParam('size', $size);
  193. }
  194. /**
  195. * Enables explain on the query.
  196. *
  197. * @param bool $explain OPTIONAL Enabled or disable explain (default = true)
  198. *
  199. * @return $this
  200. *
  201. * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-explain.html
  202. */
  203. public function setExplain($explain = true)
  204. {
  205. return $this->setParam('explain', $explain);
  206. }
  207. /**
  208. * Enables version on the query.
  209. *
  210. * @param bool $version OPTIONAL Enabled or disable version (default = true)
  211. *
  212. * @return $this
  213. *
  214. * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-version.html
  215. */
  216. public function setVersion($version = true)
  217. {
  218. return $this->setParam('version', $version);
  219. }
  220. /**
  221. * Sets the fields to be returned by the search
  222. * NOTICE php will encode modified(or named keys) array into object format in json format request
  223. * so the fields array must a sequence(list) type of array.
  224. *
  225. * @param array $fields Fields to be returned
  226. *
  227. * @return $this
  228. *
  229. * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-fields.html
  230. */
  231. public function setStoredFields(array $fields)
  232. {
  233. return $this->setParam('stored_fields', $fields);
  234. }
  235. /**
  236. * Sets the fields not stored to be returned by the search.
  237. *
  238. * @param array $fieldDataFields Fields not stored to be returned
  239. *
  240. * @return $this
  241. *
  242. * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-fielddata-fields.html
  243. */
  244. public function setFieldDataFields(array $fieldDataFields)
  245. {
  246. return $this->setParam('docvalue_fields', $fieldDataFields);
  247. }
  248. /**
  249. * Set script fields.
  250. *
  251. * @param array|\Elastica\Script\ScriptFields $scriptFields Script fields
  252. *
  253. * @return $this
  254. *
  255. * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-script-fields.html
  256. */
  257. public function setScriptFields($scriptFields)
  258. {
  259. if (is_array($scriptFields)) {
  260. $scriptFields = new ScriptFields($scriptFields);
  261. }
  262. return $this->setParam('script_fields', $scriptFields);
  263. }
  264. /**
  265. * Adds a Script to the query.
  266. *
  267. * @param string $name
  268. * @param \Elastica\Script\AbstractScript $script Script object
  269. *
  270. * @return $this
  271. */
  272. public function addScriptField($name, AbstractScript $script)
  273. {
  274. if (isset($this->_params['script_fields'])) {
  275. $this->_params['script_fields']->addScript($name, $script);
  276. } else {
  277. $this->setScriptFields([$name => $script]);
  278. }
  279. return $this;
  280. }
  281. /**
  282. * Adds an Aggregation to the query.
  283. *
  284. * @param AbstractAggregation $agg
  285. *
  286. * @return $this
  287. */
  288. public function addAggregation(AbstractAggregation $agg)
  289. {
  290. $this->_params['aggs'][] = $agg;
  291. return $this;
  292. }
  293. /**
  294. * Converts all query params to an array.
  295. *
  296. * @return array Query array
  297. */
  298. public function toArray()
  299. {
  300. if (!isset($this->_params['query']) && (0 == $this->_suggest)) {
  301. $this->setQuery(new MatchAll());
  302. }
  303. if (isset($this->_params['post_filter']) && 0 === count(($this->_params['post_filter'])->toArray())) {
  304. unset($this->_params['post_filter']);
  305. }
  306. $array = $this->_convertArrayable($this->_params);
  307. if (isset($array['suggest'])) {
  308. $array['suggest'] = $array['suggest']['suggest'];
  309. }
  310. return $array;
  311. }
  312. /**
  313. * Allows filtering of documents based on a minimum score.
  314. *
  315. * @param float $minScore Minimum score to filter documents by
  316. *
  317. * @throws \Elastica\Exception\InvalidException
  318. *
  319. * @return $this
  320. */
  321. public function setMinScore($minScore)
  322. {
  323. if (!is_numeric($minScore)) {
  324. throw new InvalidException('has to be numeric param');
  325. }
  326. return $this->setParam('min_score', $minScore);
  327. }
  328. /**
  329. * Add a suggest term.
  330. *
  331. * @param \Elastica\Suggest $suggest suggestion object
  332. *
  333. * @return $this
  334. */
  335. public function setSuggest(Suggest $suggest)
  336. {
  337. $this->setParam('suggest', $suggest);
  338. $this->_suggest = 1;
  339. return $this;
  340. }
  341. /**
  342. * Add a Rescore.
  343. *
  344. * @param mixed $rescore suggestion object
  345. *
  346. * @return $this
  347. */
  348. public function setRescore($rescore)
  349. {
  350. if (is_array($rescore)) {
  351. $buffer = [];
  352. foreach ($rescore as $rescoreQuery) {
  353. $buffer[] = $rescoreQuery;
  354. }
  355. } else {
  356. $buffer = $rescore;
  357. }
  358. return $this->setParam('rescore', $buffer);
  359. }
  360. /**
  361. * Sets the _source field to be returned with every hit.
  362. *
  363. * @param array|bool $params Fields to be returned or false to disable source
  364. *
  365. * @return $this
  366. *
  367. * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-source-filtering.html
  368. */
  369. public function setSource($params)
  370. {
  371. return $this->setParam('_source', $params);
  372. }
  373. /**
  374. * Sets post_filter argument for the query. The filter is applied after the query has executed.
  375. *
  376. * @param array|\Elastica\Query\AbstractQuery $filter
  377. *
  378. * @return $this
  379. *
  380. * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-post-filter.html
  381. */
  382. public function setPostFilter(AbstractQuery $filter)
  383. {
  384. return $this->setParam('post_filter', $filter);
  385. }
  386. }