PageRenderTime 43ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/Elastica/Query.php

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