script-score-query.asciidoc 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. [[query-dsl-script-score-query]]
  2. === Script score query
  3. ++++
  4. <titleabbrev>Script score</titleabbrev>
  5. ++++
  6. Uses a <<modules-scripting,script>> to provide a custom score for returned
  7. documents.
  8. The `script_score` query is useful if, for example, a scoring function is expensive and you only need to calculate the score of a filtered set of documents.
  9. [[script-score-query-ex-request]]
  10. ==== Example request
  11. The following `script_score` query assigns each returned document a score equal to the `likes` field value divided by `10`.
  12. [source,console]
  13. --------------------------------------------------
  14. GET /_search
  15. {
  16. "query" : {
  17. "script_score" : {
  18. "query" : {
  19. "match": { "message": "elasticsearch" }
  20. },
  21. "script" : {
  22. "source" : "doc['likes'].value / 10 "
  23. }
  24. }
  25. }
  26. }
  27. --------------------------------------------------
  28. [[script-score-top-level-params]]
  29. ==== Top-level parameters for `script_score`
  30. `query`::
  31. (Required, query object) Query used to return documents.
  32. `script`::
  33. +
  34. --
  35. (Required, <<modules-scripting-using,script object>>) Script used to compute the score of documents returned by the `query`.
  36. IMPORTANT: Final relevance scores from the `script_score` query cannot be
  37. negative. To support certain search optimizations, Lucene requires
  38. scores be positive or `0`.
  39. --
  40. `min_score`::
  41. (Optional, float) Documents with a <<relevance-scores,relevance score>> lower
  42. than this floating point number are excluded from the search results.
  43. [[script-score-query-notes]]
  44. ==== Notes
  45. [[script-score-access-scores]]
  46. ===== Use relevance scores in a script
  47. Within a script, you can
  48. {ref}/modules-scripting-fields.html#scripting-score[access]
  49. the `_score` variable which represents the current relevance score of a
  50. document.
  51. [[script-score-predefined-functions]]
  52. ===== Predefined functions
  53. You can use any of the available {painless}/painless-contexts.html[painless
  54. functions] in your `script`. You can also use the following predefined functions
  55. to customize scoring:
  56. * <<script-score-saturation>>
  57. * <<script-score-sigmoid>>
  58. * <<random-score-function>>
  59. * <<decay-functions-numeric-fields>>
  60. * <<decay-functions-geo-fields>>
  61. * <<decay-functions-date-fields>>
  62. * <<script-score-functions-vector-fields>>
  63. We suggest using these predefined functions instead of writing your own.
  64. These functions take advantage of efficiencies from {es}' internal mechanisms.
  65. [[script-score-saturation]]
  66. ====== Saturation
  67. `saturation(value,k) = value/(k + value)`
  68. [source,js]
  69. --------------------------------------------------
  70. "script" : {
  71. "source" : "saturation(doc['likes'].value, 1)"
  72. }
  73. --------------------------------------------------
  74. // NOTCONSOLE
  75. [[script-score-sigmoid]]
  76. ====== Sigmoid
  77. `sigmoid(value, k, a) = value^a/ (k^a + value^a)`
  78. [source,js]
  79. --------------------------------------------------
  80. "script" : {
  81. "source" : "sigmoid(doc['likes'].value, 2, 1)"
  82. }
  83. --------------------------------------------------
  84. // NOTCONSOLE
  85. [[random-score-function]]
  86. ====== Random score function
  87. `random_score` function generates scores that are uniformly distributed
  88. from 0 up to but not including 1.
  89. `randomScore` function has the following syntax:
  90. `randomScore(<seed>, <fieldName>)`.
  91. It has a required parameter - `seed` as an integer value,
  92. and an optional parameter - `fieldName` as a string value.
  93. [source,js]
  94. --------------------------------------------------
  95. "script" : {
  96. "source" : "randomScore(100, '_seq_no')"
  97. }
  98. --------------------------------------------------
  99. // NOTCONSOLE
  100. If the `fieldName` parameter is omitted, the internal Lucene
  101. document ids will be used as a source of randomness. This is very efficient,
  102. but unfortunately not reproducible since documents might be renumbered
  103. by merges.
  104. [source,js]
  105. --------------------------------------------------
  106. "script" : {
  107. "source" : "randomScore(100)"
  108. }
  109. --------------------------------------------------
  110. // NOTCONSOLE
  111. Note that documents that are within the same shard and have the
  112. same value for field will get the same score, so it is usually desirable
  113. to use a field that has unique values for all documents across a shard.
  114. A good default choice might be to use the `_seq_no`
  115. field, whose only drawback is that scores will change if the document is
  116. updated since update operations also update the value of the `_seq_no` field.
  117. [[decay-functions-numeric-fields]]
  118. ====== Decay functions for numeric fields
  119. You can read more about decay functions
  120. {ref}/query-dsl-function-score-query.html#function-decay[here].
  121. * `double decayNumericLinear(double origin, double scale, double offset, double decay, double docValue)`
  122. * `double decayNumericExp(double origin, double scale, double offset, double decay, double docValue)`
  123. * `double decayNumericGauss(double origin, double scale, double offset, double decay, double docValue)`
  124. [source,js]
  125. --------------------------------------------------
  126. "script" : {
  127. "source" : "decayNumericLinear(params.origin, params.scale, params.offset, params.decay, doc['dval'].value)",
  128. "params": { <1>
  129. "origin": 20,
  130. "scale": 10,
  131. "decay" : 0.5,
  132. "offset" : 0
  133. }
  134. }
  135. --------------------------------------------------
  136. // NOTCONSOLE
  137. <1> Using `params` allows to compile the script only once, even if params change.
  138. [[decay-functions-geo-fields]]
  139. ====== Decay functions for geo fields
  140. * `double decayGeoLinear(String originStr, String scaleStr, String offsetStr, double decay, GeoPoint docValue)`
  141. * `double decayGeoExp(String originStr, String scaleStr, String offsetStr, double decay, GeoPoint docValue)`
  142. * `double decayGeoGauss(String originStr, String scaleStr, String offsetStr, double decay, GeoPoint docValue)`
  143. [source,js]
  144. --------------------------------------------------
  145. "script" : {
  146. "source" : "decayGeoExp(params.origin, params.scale, params.offset, params.decay, doc['location'].value)",
  147. "params": {
  148. "origin": "40, -70.12",
  149. "scale": "200km",
  150. "offset": "0km",
  151. "decay" : 0.2
  152. }
  153. }
  154. --------------------------------------------------
  155. // NOTCONSOLE
  156. [[decay-functions-date-fields]]
  157. ====== Decay functions for date fields
  158. * `double decayDateLinear(String originStr, String scaleStr, String offsetStr, double decay, JodaCompatibleZonedDateTime docValueDate)`
  159. * `double decayDateExp(String originStr, String scaleStr, String offsetStr, double decay, JodaCompatibleZonedDateTime docValueDate)`
  160. * `double decayDateGauss(String originStr, String scaleStr, String offsetStr, double decay, JodaCompatibleZonedDateTime docValueDate)`
  161. [source,js]
  162. --------------------------------------------------
  163. "script" : {
  164. "source" : "decayDateGauss(params.origin, params.scale, params.offset, params.decay, doc['date'].value)",
  165. "params": {
  166. "origin": "2008-01-01T01:00:00Z",
  167. "scale": "1h",
  168. "offset" : "0",
  169. "decay" : 0.5
  170. }
  171. }
  172. --------------------------------------------------
  173. // NOTCONSOLE
  174. NOTE: Decay functions on dates are limited to dates in the default format
  175. and default time zone. Also calculations with `now` are not supported.
  176. [[script-score-functions-vector-fields]]
  177. ====== Functions for vector fields
  178. <<vector-functions, Functions for vector fields>> are accessible through
  179. `script_score` query.
  180. [[script-score-faster-alt]]
  181. ===== Faster alternatives
  182. The `script_score` query calculates the score for
  183. every matching document, or hit. There are faster alternative query types that
  184. can efficiently skip non-competitive hits:
  185. * If you want to boost documents on some static fields, use the
  186. <<query-dsl-rank-feature-query, `rank_feature`>> query.
  187. * If you want to boost documents closer to a date or geographic point, use the
  188. <<query-dsl-distance-feature-query, `distance_feature`>> query.
  189. [[script-score-function-score-transition]]
  190. ===== Transition from the function score query
  191. We are deprecating the <<query-dsl-function-score-query, `function_score`>>
  192. query. We recommend using the `script_score` query instead.
  193. You can implement the following functions from the `function_score` query using
  194. the `script_score` query:
  195. * <<script-score>>
  196. * <<weight>>
  197. * <<random-score>>
  198. * <<field-value-factor>>
  199. * <<decay-functions>>
  200. [[script-score]]
  201. ====== `script_score`
  202. What you used in `script_score` of the Function Score query, you
  203. can copy into the Script Score query. No changes here.
  204. [[weight]]
  205. ====== `weight`
  206. `weight` function can be implemented in the Script Score query through
  207. the following script:
  208. [source,js]
  209. --------------------------------------------------
  210. "script" : {
  211. "source" : "params.weight * _score",
  212. "params": {
  213. "weight": 2
  214. }
  215. }
  216. --------------------------------------------------
  217. // NOTCONSOLE
  218. [[random-score]]
  219. ====== `random_score`
  220. Use `randomScore` function
  221. as described in <<random-score-function, random score function>>.
  222. [[field-value-factor]]
  223. ====== `field_value_factor`
  224. `field_value_factor` function can be easily implemented through script:
  225. [source,js]
  226. --------------------------------------------------
  227. "script" : {
  228. "source" : "Math.log10(doc['field'].value * params.factor)",
  229. params" : {
  230. "factor" : 5
  231. }
  232. }
  233. --------------------------------------------------
  234. // NOTCONSOLE
  235. For checking if a document has a missing value, you can use
  236. `doc['field'].size() == 0`. For example, this script will use
  237. a value `1` if a document doesn't have a field `field`:
  238. [source,js]
  239. --------------------------------------------------
  240. "script" : {
  241. "source" : "Math.log10((doc['field'].size() == 0 ? 1 : doc['field'].value()) * params.factor)",
  242. params" : {
  243. "factor" : 5
  244. }
  245. }
  246. --------------------------------------------------
  247. // NOTCONSOLE
  248. This table lists how `field_value_factor` modifiers can be implemented
  249. through a script:
  250. [cols="<,<",options="header",]
  251. |=======================================================================
  252. | Modifier | Implementation in Script Score
  253. | `none` | -
  254. | `log` | `Math.log10(doc['f'].value)`
  255. | `log1p` | `Math.log10(doc['f'].value + 1)`
  256. | `log2p` | `Math.log10(doc['f'].value + 2)`
  257. | `ln` | `Math.log(doc['f'].value)`
  258. | `ln1p` | `Math.log(doc['f'].value + 1)`
  259. | `ln2p` | `Math.log(doc['f'].value + 2)`
  260. | `square` | `Math.pow(doc['f'].value, 2)`
  261. | `sqrt` | `Math.sqrt(doc['f'].value)`
  262. | `reciprocal` | `1.0 / doc['f'].value`
  263. |=======================================================================
  264. [[decay-functions]]
  265. ====== `decay` functions
  266. The `script_score` query has equivalent <<decay-functions, decay functions>>
  267. that can be used in script.
  268. include::{es-repo-dir}/vectors/vector-functions.asciidoc[]