fields.asciidoc 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. [[modules-scripting-fields]]
  2. == Accessing document fields and special variables
  3. Depending on where a script is used, it will have access to certain special
  4. variables and document fields.
  5. [discrete]
  6. == Update scripts
  7. A script used in the <<docs-update,update>>,
  8. <<docs-update-by-query,update-by-query>>, or <<docs-reindex,reindex>>
  9. API will have access to the `ctx` variable which exposes:
  10. [horizontal]
  11. `ctx._source`:: Access to the document <<mapping-source-field,`_source` field>>.
  12. `ctx.op`:: The operation that should be applied to the document: `index` or `delete`.
  13. `ctx._index` etc:: Access to <<mapping-fields,document metadata fields>>, some of which may be read-only.
  14. These scripts do not have access to the `doc` variable and have to use `ctx` to access the documents they operate on.
  15. [discrete]
  16. == Search and aggregation scripts
  17. With the exception of <<script-fields,script fields>> which are
  18. executed once per search hit, scripts used in search and aggregations will be
  19. executed once for every document which might match a query or an aggregation.
  20. Depending on how many documents you have, this could mean millions or billions
  21. of executions: these scripts need to be fast!
  22. Field values can be accessed from a script using
  23. <<modules-scripting-doc-vals,doc-values>>,
  24. <<modules-scripting-source, the `_source` field>>, or
  25. <<modules-scripting-stored, stored fields>>,
  26. each of which is explained below.
  27. [[scripting-score]]
  28. [discrete]
  29. === Accessing the score of a document within a script
  30. Scripts used in the <<query-dsl-function-score-query,`function_score` query>>,
  31. in <<sort-search-results,script-based sorting>>, or in
  32. <<search-aggregations,aggregations>> have access to the `_score` variable which
  33. represents the current relevance score of a document.
  34. Here's an example of using a script in a
  35. <<query-dsl-function-score-query,`function_score` query>> to alter the
  36. relevance `_score` of each document:
  37. [source,console]
  38. -------------------------------------
  39. PUT my-index-000001/_doc/1?refresh
  40. {
  41. "text": "quick brown fox",
  42. "popularity": 1
  43. }
  44. PUT my-index-000001/_doc/2?refresh
  45. {
  46. "text": "quick fox",
  47. "popularity": 5
  48. }
  49. GET my-index-000001/_search
  50. {
  51. "query": {
  52. "function_score": {
  53. "query": {
  54. "match": {
  55. "text": "quick brown fox"
  56. }
  57. },
  58. "script_score": {
  59. "script": {
  60. "lang": "expression",
  61. "source": "_score * doc['popularity']"
  62. }
  63. }
  64. }
  65. }
  66. }
  67. -------------------------------------
  68. [discrete]
  69. [[scripting-term-statistics]]
  70. === Accessing term statistics of a document within a script
  71. Scripts used in a <<query-dsl-script-score-query,`script_score`>> query have access to the `_termStats` variable which provides statistical information about the terms in the child query.
  72. In the following example, `_termStats` is used within a <<query-dsl-script-score-query,`script_score`>> query to retrieve the average term frequency for the terms `quick`, `brown`, and `fox` in the `text` field:
  73. [source,console]
  74. -------------------------------------
  75. PUT my-index-000001/_doc/1?refresh
  76. {
  77. "text": "quick brown fox"
  78. }
  79. PUT my-index-000001/_doc/2?refresh
  80. {
  81. "text": "quick fox"
  82. }
  83. GET my-index-000001/_search
  84. {
  85. "query": {
  86. "script_score": {
  87. "query": { <1>
  88. "match": {
  89. "text": "quick brown fox"
  90. }
  91. },
  92. "script": {
  93. "source": "_termStats.termFreq().getAverage()" <2>
  94. }
  95. }
  96. }
  97. }
  98. -------------------------------------
  99. <1> Child query used to infer the field and the terms considered in term statistics.
  100. <2> The script calculates the average document frequency for the terms in the query using `_termStats`.
  101. `_termStats` provides access to the following functions for working with term statistics:
  102. - `uniqueTermsCount`: Returns the total number of unique terms in the query. This value is the same across all documents.
  103. - `matchedTermsCount`: Returns the count of query terms that matched within the current document.
  104. - `docFreq`: Provides document frequency statistics for the terms in the query, indicating how many documents contain each term. This value is consistent across all documents.
  105. - `totalTermFreq`: Provides the total frequency of terms across all documents, representing how often each term appears in the entire corpus. This value is consistent across all documents.
  106. - `termFreq`: Returns the frequency of query terms within the current document, showing how often each term appears in that document.
  107. [NOTE]
  108. .Functions returning aggregated statistics
  109. ===================================================
  110. The `docFreq`, `termFreq` and `totalTermFreq` functions return objects that represent statistics across all terms of the child query.
  111. Statistics provides support for the following methods:
  112. `getAverage()`: Returns the average value of the metric.
  113. `getMin()`: Returns the minimum value of the metric.
  114. `getMax()`: Returns the maximum value of the metric.
  115. `getSum()`: Returns the sum of the metric values.
  116. `getCount()`: Returns the count of terms included in the metric calculation.
  117. ===================================================
  118. [NOTE]
  119. .Painless language required
  120. ===================================================
  121. The `_termStats` variable is only available when using the <<modules-scripting-painless, Painless>> scripting language.
  122. ===================================================
  123. [discrete]
  124. [[modules-scripting-doc-vals]]
  125. === Doc values
  126. By far the fastest most efficient way to access a field value from a
  127. script is to use the `doc['field_name']` syntax, which retrieves the field
  128. value from <<doc-values,doc values>>. Doc values are a columnar field value
  129. store, enabled by default on all fields except for <<text,analyzed `text` fields>>.
  130. [source,console]
  131. -------------------------------
  132. PUT my-index-000001/_doc/1?refresh
  133. {
  134. "cost_price": 100
  135. }
  136. GET my-index-000001/_search
  137. {
  138. "script_fields": {
  139. "sales_price": {
  140. "script": {
  141. "lang": "expression",
  142. "source": "doc['cost_price'] * markup",
  143. "params": {
  144. "markup": 0.2
  145. }
  146. }
  147. }
  148. }
  149. }
  150. -------------------------------
  151. Doc-values can only return "simple" field values like numbers, dates, geo-
  152. points, terms, etc, or arrays of these values if the field is multi-valued.
  153. It cannot return JSON objects.
  154. [NOTE]
  155. .Missing fields
  156. ===================================================
  157. The `doc['field']` will throw an error if `field` is missing from the mappings.
  158. In `painless`, a check can first be done with `doc.containsKey('field')` to guard
  159. accessing the `doc` map. Unfortunately, there is no way to check for the
  160. existence of the field in mappings in an `expression` script.
  161. ===================================================
  162. [NOTE]
  163. .Doc values and `text` fields
  164. ===================================================
  165. The `doc['field']` syntax can also be used for <<text,analyzed `text` fields>>
  166. if <<fielddata-mapping-param,`fielddata`>> is enabled, but *BEWARE*: enabling fielddata on a
  167. `text` field requires loading all of the terms into the JVM heap, which can be
  168. very expensive both in terms of memory and CPU. It seldom makes sense to
  169. access `text` fields from scripts.
  170. ===================================================
  171. [discrete]
  172. [[modules-scripting-source]]
  173. === The document `_source`
  174. The document <<mapping-source-field,`_source`>> can be accessed using the
  175. `_source.field_name` syntax. The `_source` is loaded as a map-of-maps, so
  176. properties within object fields can be accessed as, for example,
  177. `_source.name.first`.
  178. [IMPORTANT]
  179. .Prefer doc-values to _source
  180. =========================================================
  181. Accessing the `_source` field is much slower than using doc-values. The
  182. _source field is optimised for returning several fields per result, while doc
  183. values are optimised for accessing the value of a specific field in many
  184. documents.
  185. It makes sense to use `_source` when generating a
  186. <<script-fields,script field>> for the top ten hits from a
  187. search result but, for other search and aggregation use cases, always prefer
  188. using doc values.
  189. =========================================================
  190. For instance:
  191. [source,console]
  192. -------------------------------
  193. PUT my-index-000001
  194. {
  195. "mappings": {
  196. "properties": {
  197. "first_name": {
  198. "type": "text"
  199. },
  200. "last_name": {
  201. "type": "text"
  202. }
  203. }
  204. }
  205. }
  206. PUT my-index-000001/_doc/1?refresh
  207. {
  208. "first_name": "Barry",
  209. "last_name": "White"
  210. }
  211. GET my-index-000001/_search
  212. {
  213. "script_fields": {
  214. "full_name": {
  215. "script": {
  216. "lang": "painless",
  217. "source": "params._source.first_name + ' ' + params._source.last_name"
  218. }
  219. }
  220. }
  221. }
  222. -------------------------------
  223. [discrete]
  224. [[modules-scripting-stored]]
  225. === Stored fields
  226. _Stored fields_ -- fields explicitly marked as
  227. <<mapping-store,`"store": true`>> in the mapping -- can be accessed using the
  228. `_fields['field_name'].value` or `_fields['field_name']` syntax:
  229. [source,console]
  230. -------------------------------
  231. PUT my-index-000001
  232. {
  233. "mappings": {
  234. "properties": {
  235. "full_name": {
  236. "type": "text",
  237. "store": true
  238. },
  239. "title": {
  240. "type": "text",
  241. "store": true
  242. }
  243. }
  244. }
  245. }
  246. PUT my-index-000001/_doc/1?refresh
  247. {
  248. "full_name": "Alice Ball",
  249. "title": "Professor"
  250. }
  251. GET my-index-000001/_search
  252. {
  253. "script_fields": {
  254. "name_with_title": {
  255. "script": {
  256. "lang": "painless",
  257. "source": "params._fields['title'].value + ' ' + params._fields['full_name'].value"
  258. }
  259. }
  260. }
  261. }
  262. -------------------------------
  263. [TIP]
  264. .Stored vs `_source`
  265. =======================================================
  266. The `_source` field is just a special stored field, so the performance is
  267. similar to that of other stored fields. The `_source` provides access to the
  268. original document body that was indexed (including the ability to distinguish
  269. `null` values from empty fields, single-value arrays from plain scalars, etc).
  270. The only time it really makes sense to use stored fields instead of the
  271. `_source` field is when the `_source` is very large and it is less costly to
  272. access a few small stored fields instead of the entire `_source`.
  273. =======================================================