script-score-query.asciidoc 10 KB

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