FunctionScore.php 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. <?php
  2. namespace Elastica\Query;
  3. use Elastica\Script\AbstractScript;
  4. /**
  5. * Class FunctionScore.
  6. *
  7. * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-function-score-query.html
  8. */
  9. class FunctionScore extends AbstractQuery
  10. {
  11. const BOOST_MODE_MULTIPLY = 'multiply';
  12. const BOOST_MODE_REPLACE = 'replace';
  13. const BOOST_MODE_SUM = 'sum';
  14. const BOOST_MODE_AVERAGE = 'avg';
  15. const BOOST_MODE_MAX = 'max';
  16. const BOOST_MODE_MIN = 'min';
  17. const SCORE_MODE_MULTIPLY = 'multiply';
  18. const SCORE_MODE_SUM = 'sum';
  19. const SCORE_MODE_AVERAGE = 'avg';
  20. const SCORE_MODE_FIRST = 'first';
  21. const SCORE_MODE_MAX = 'max';
  22. const SCORE_MODE_MIN = 'min';
  23. const DECAY_GAUSS = 'gauss';
  24. const DECAY_EXPONENTIAL = 'exp';
  25. const DECAY_LINEAR = 'linear';
  26. const FIELD_VALUE_FACTOR_MODIFIER_NONE = 'none';
  27. const FIELD_VALUE_FACTOR_MODIFIER_LOG = 'log';
  28. const FIELD_VALUE_FACTOR_MODIFIER_LOG1P = 'log1p';
  29. const FIELD_VALUE_FACTOR_MODIFIER_LOG2P = 'log2p';
  30. const FIELD_VALUE_FACTOR_MODIFIER_LN = 'ln';
  31. const FIELD_VALUE_FACTOR_MODIFIER_LN1P = 'ln1p';
  32. const FIELD_VALUE_FACTOR_MODIFIER_LN2P = 'ln2p';
  33. const FIELD_VALUE_FACTOR_MODIFIER_SQUARE = 'square';
  34. const FIELD_VALUE_FACTOR_MODIFIER_SQRT = 'sqrt';
  35. const FIELD_VALUE_FACTOR_MODIFIER_RECIPROCAL = 'reciprocal';
  36. const MULTI_VALUE_MODE_MIN = 'min';
  37. const MULTI_VALUE_MODE_MAX = 'max';
  38. const MULTI_VALUE_MODE_AVG = 'avg';
  39. const MULTI_VALUE_MODE_SUM = 'sum';
  40. const RANDOM_SCORE_FIELD_ID = '_id';
  41. const RANDOM_SCORE_FIELD_SEQ_NO = '_seq_no';
  42. protected $_functions = [];
  43. /**
  44. * Set the child query for this function_score query.
  45. *
  46. * @param AbstractQuery $query
  47. *
  48. * @return $this
  49. */
  50. public function setQuery(AbstractQuery $query)
  51. {
  52. return $this->setParam('query', $query);
  53. }
  54. /**
  55. * Add a function to the function_score query.
  56. *
  57. * @param string $functionType valid values are DECAY_* constants and script_score
  58. * @param array|float $functionParams the body of the function. See documentation for proper syntax.
  59. * @param AbstractQuery $filter optional filter to apply to the function
  60. * @param float $weight function weight
  61. *
  62. * @return $this
  63. */
  64. public function addFunction($functionType, $functionParams, AbstractQuery $filter = null, $weight = null)
  65. {
  66. $function = [
  67. $functionType => $functionParams,
  68. ];
  69. if (!is_null($filter)) {
  70. $function['filter'] = $filter;
  71. }
  72. if (null !== $weight) {
  73. $function['weight'] = $weight;
  74. }
  75. $this->_functions[] = $function;
  76. return $this;
  77. }
  78. /**
  79. * Add a script_score function to the query.
  80. *
  81. * @param \Elastica\Script\AbstractScript $script a Script object
  82. * @param AbstractQuery $filter an optional filter to apply to the function
  83. * @param float $weight the weight of the function
  84. *
  85. * @return $this
  86. */
  87. public function addScriptScoreFunction(AbstractScript $script, AbstractQuery $filter = null, $weight = null)
  88. {
  89. return $this->addFunction('script_score', $script, $filter, $weight);
  90. }
  91. /**
  92. * Add a decay function to the query.
  93. *
  94. * @param string $function see DECAY_* constants for valid options
  95. * @param string $field the document field on which to perform the decay function
  96. * @param string $origin the origin value for this decay function
  97. * @param string $scale a scale to define the rate of decay for this function
  98. * @param string $offset If defined, this function will only be computed for documents with a distance from the origin greater than this value
  99. * @param float $decay optionally defines how documents are scored at the distance given by the $scale parameter
  100. * @param float $weight optional factor by which to multiply the score at the value provided by the $scale parameter
  101. * @param AbstractQuery $filter a filter associated with this function
  102. * @param string $multiValueMode see MULTI_VALUE_MODE_* constants for valid options
  103. *
  104. * @return $this
  105. */
  106. public function addDecayFunction(
  107. $function,
  108. $field,
  109. $origin,
  110. $scale,
  111. $offset = null,
  112. $decay = null,
  113. $weight = null,
  114. AbstractQuery $filter = null,
  115. $multiValueMode = null
  116. ) {
  117. $functionParams = [
  118. $field => [
  119. 'origin' => $origin,
  120. 'scale' => $scale,
  121. ],
  122. ];
  123. if (!is_null($offset)) {
  124. $functionParams[$field]['offset'] = $offset;
  125. }
  126. if (!is_null($decay)) {
  127. $functionParams[$field]['decay'] = (float) $decay;
  128. }
  129. if (null !== $multiValueMode) {
  130. $functionParams['multi_value_mode'] = $multiValueMode;
  131. }
  132. return $this->addFunction($function, $functionParams, $filter, $weight);
  133. }
  134. public function addFieldValueFactorFunction(
  135. $field,
  136. $factor = null,
  137. $modifier = null,
  138. $missing = null,
  139. $weight = null,
  140. AbstractQuery $filter = null
  141. ) {
  142. $functionParams = [
  143. 'field' => $field,
  144. ];
  145. if (!is_null($factor)) {
  146. $functionParams['factor'] = $factor;
  147. }
  148. if (!is_null($modifier)) {
  149. $functionParams['modifier'] = $modifier;
  150. }
  151. if (!is_null($missing)) {
  152. $functionParams['missing'] = $missing;
  153. }
  154. return $this->addFunction('field_value_factor', $functionParams, $filter, $weight);
  155. }
  156. /**
  157. * @param float $weight the weight of the function
  158. * @param AbstractQuery $filter a filter associated with this function
  159. *
  160. * @return $this
  161. */
  162. public function addWeightFunction($weight, AbstractQuery $filter = null)
  163. {
  164. return $this->addFunction('weight', $weight, $filter);
  165. }
  166. /**
  167. * Add a random_score function to the query.
  168. *
  169. * @param number $seed the seed value
  170. * @param AbstractQuery $filter a filter associated with this function
  171. * @param float $weight an optional boost value associated with this function
  172. * @param string $field the field to be used for random number generation
  173. *
  174. * @return $this
  175. */
  176. public function addRandomScoreFunction($seed, AbstractQuery $filter = null, $weight = null, $field = null)
  177. {
  178. $functionParams = [
  179. 'seed' => $seed,
  180. ];
  181. if (null !== $field) {
  182. $functionParams['field'] = $field;
  183. }
  184. return $this->addFunction('random_score', $functionParams, $filter, $weight);
  185. }
  186. /**
  187. * Set an overall boost value for this query.
  188. *
  189. * @param float $boost
  190. *
  191. * @return $this
  192. */
  193. public function setBoost($boost)
  194. {
  195. return $this->setParam('boost', (float) $boost);
  196. }
  197. /**
  198. * Restrict the combined boost of the function_score query and its child query.
  199. *
  200. * @param float $maxBoost
  201. *
  202. * @return $this
  203. */
  204. public function setMaxBoost($maxBoost)
  205. {
  206. return $this->setParam('max_boost', (float) $maxBoost);
  207. }
  208. /**
  209. * The boost mode determines how the score of this query is combined with that of the child query.
  210. *
  211. * @param string $mode see BOOST_MODE_* constants for valid options. Default is multiply.
  212. *
  213. * @return $this
  214. */
  215. public function setBoostMode($mode)
  216. {
  217. return $this->setParam('boost_mode', $mode);
  218. }
  219. /**
  220. * If set, this query will return results in random order.
  221. *
  222. * @param int $seed set a seed value to return results in the same random order for consistent pagination
  223. *
  224. * @return $this
  225. */
  226. public function setRandomScore($seed = null)
  227. {
  228. $seedParam = new \stdClass();
  229. if (!is_null($seed)) {
  230. $seedParam->seed = $seed;
  231. }
  232. return $this->setParam('random_score', $seedParam);
  233. }
  234. /**
  235. * Set the score method.
  236. *
  237. * @param string $mode see SCORE_MODE_* constants for valid options. Default is multiply.
  238. *
  239. * @return $this
  240. */
  241. public function setScoreMode($mode)
  242. {
  243. return $this->setParam('score_mode', $mode);
  244. }
  245. /**
  246. * Set min_score option.
  247. *
  248. * @param float $minScore
  249. *
  250. * @return $this
  251. */
  252. public function setMinScore($minScore)
  253. {
  254. return $this->setParam('min_score', (float) $minScore);
  255. }
  256. /**
  257. * @return array
  258. */
  259. public function toArray()
  260. {
  261. if (sizeof($this->_functions)) {
  262. $this->setParam('functions', $this->_functions);
  263. }
  264. return parent::toArray();
  265. }
  266. }