retrieve-selected-fields.asciidoc 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795
  1. [[search-fields]]
  2. == Retrieve selected fields from a search
  3. ++++
  4. <titleabbrev>Retrieve selected fields</titleabbrev>
  5. ++++
  6. By default, each hit in the search response includes the document
  7. <<mapping-source-field,`_source`>>, which is the entire JSON object that was
  8. provided when indexing the document. There are two recommended methods to
  9. retrieve selected fields from a search query:
  10. * Use the <<search-fields-param,`fields` option>> to extract the values of
  11. fields present in the index mapping
  12. * Use the <<source-filtering,`_source` option>> if you need to access the original data that was passed at index time
  13. You can use both of these methods, though the `fields` option is preferred
  14. because it consults both the document data and index mappings. In some
  15. instances, you might want to use <<field-retrieval-methods,other methods>> of
  16. retrieving data.
  17. [discrete]
  18. [[search-fields-param]]
  19. === The `fields` option
  20. To retrieve specific fields in the search response, use the `fields` parameter.
  21. // tag::fields-param-desc[]
  22. Because it consults the index mappings, the `fields` parameter provides several
  23. advantages over referencing the `_source` directly. Specifically, the `fields`
  24. parameter:
  25. * Returns each value in a standardized way that matches its mapping type
  26. * Accepts <<multi-fields,multi-fields>> and <<field-alias,field aliases>>
  27. * Formats dates and spatial data types
  28. * Retrieves <<runtime-retrieving-fields,runtime field values>>
  29. * Returns fields calculated by a script at index time
  30. * Returns fields from related indices using <<lookup-runtime-fields, lookup runtime fields>>
  31. // end::fields-param-desc[]
  32. Other mapping options are also respected, including
  33. <<ignore-above,`ignore_above`>>, <<ignore-malformed,`ignore_malformed`>>, and
  34. <<null-value,`null_value`>>.
  35. The `fields` option returns values in the way that matches how {es} indexes
  36. them. For standard fields, this means that the `fields` option looks in
  37. `_source` to find the values, then parses and formats them using the mappings.
  38. [discrete]
  39. [[search-fields-request]]
  40. ==== Retrieve specific fields
  41. The following search request uses the `fields` parameter to retrieve values
  42. for the `user.id` field, all fields starting with `http.response.`, and the
  43. `@timestamp` field.
  44. Using object notation, you can pass a <<search-api-fields,`format`>> argument to
  45. customize the format of returned date or geospatial values.
  46. [source,console]
  47. ----
  48. POST my-index-000001/_search
  49. {
  50. "query": {
  51. "match": {
  52. "user.id": "kimchy"
  53. }
  54. },
  55. "fields": [
  56. "user.id",
  57. "http.response.*", <1>
  58. {
  59. "field": "@timestamp",
  60. "format": "epoch_millis" <2>
  61. }
  62. ],
  63. "_source": false
  64. }
  65. ----
  66. // TEST[setup:my_index]
  67. // TEST[s/_search/_search\?filter_path=hits/]
  68. // tag::fields-param-callouts[]
  69. <1> Both full field names and wildcard patterns are accepted.
  70. <2> Use the `format` parameter to apply a custom format for the field's values.
  71. // end::fields-param-callouts[]
  72. NOTE: By default, document metadata fields like `_id` or `_index` are not
  73. returned when the requested `fields` option uses wildcard patterns like `*`.
  74. However, when explicitly requested using the field name, the `_id`, `_routing`,
  75. `_ignored`, `_index` and `_version` metadata fields can be retrieved.
  76. [discrete]
  77. [[search-fields-response]]
  78. ==== Response always returns an array
  79. The `fields` response always returns an array of values for each field,
  80. even when there is a single value in the `_source`. This is because {es} has
  81. no dedicated array type, and any field could contain multiple values. The
  82. `fields` parameter also does not guarantee that array values are returned in
  83. a specific order. See the mapping documentation on <<array,arrays>> for more
  84. background.
  85. The response includes values as a flat list in the `fields` section for each
  86. hit. Because the `fields` parameter doesn't fetch entire objects, only leaf
  87. fields are returned.
  88. [source,console-result]
  89. ----
  90. {
  91. "hits" : {
  92. "total" : {
  93. "value" : 1,
  94. "relation" : "eq"
  95. },
  96. "max_score" : 1.0,
  97. "hits" : [
  98. {
  99. "_index" : "my-index-000001",
  100. "_id" : "0",
  101. "_score" : 1.0,
  102. "fields" : {
  103. "user.id" : [
  104. "kimchy"
  105. ],
  106. "@timestamp" : [
  107. "4098435132000"
  108. ],
  109. "http.response.bytes": [
  110. 1070000
  111. ],
  112. "http.response.status_code": [
  113. 200
  114. ]
  115. }
  116. }
  117. ]
  118. }
  119. }
  120. ----
  121. // TESTRESPONSE[s/"max_score" : 1.0/"max_score" : $body.hits.max_score/]
  122. // TESTRESPONSE[s/"_score" : 1.0/"_score" : $body.hits.hits.0._score/]
  123. [discrete]
  124. [[search-fields-nested]]
  125. ==== Retrieve nested fields
  126. [%collapsible]
  127. ====
  128. The `fields` response for <<nested,`nested` fields>> is slightly different from that
  129. of regular object fields. While leaf values inside regular `object` fields are
  130. returned as a flat list, values inside `nested` fields are grouped to maintain the
  131. independence of each object inside the original nested array.
  132. For each entry inside a nested field array, values are again returned as a flat list
  133. unless there are other `nested` fields inside the parent nested object, in which case
  134. the same procedure is repeated again for the deeper nested fields.
  135. Given the following mapping where `user` is a nested field, after indexing
  136. the following document and retrieving all fields under the `user` field:
  137. [source,console]
  138. --------------------------------------------------
  139. PUT my-index-000001
  140. {
  141. "mappings": {
  142. "properties": {
  143. "group" : { "type" : "keyword" },
  144. "user": {
  145. "type": "nested",
  146. "properties": {
  147. "first" : { "type" : "keyword" },
  148. "last" : { "type" : "keyword" }
  149. }
  150. }
  151. }
  152. }
  153. }
  154. PUT my-index-000001/_doc/1?refresh=true
  155. {
  156. "group" : "fans",
  157. "user" : [
  158. {
  159. "first" : "John",
  160. "last" : "Smith"
  161. },
  162. {
  163. "first" : "Alice",
  164. "last" : "White"
  165. }
  166. ]
  167. }
  168. POST my-index-000001/_search
  169. {
  170. "fields": ["*"],
  171. "_source": false
  172. }
  173. --------------------------------------------------
  174. The response will group `first` and `last` name instead of
  175. returning them as a flat list.
  176. [source,console-result]
  177. ----
  178. {
  179. "took": 2,
  180. "timed_out": false,
  181. "_shards": {
  182. "total": 1,
  183. "successful": 1,
  184. "skipped": 0,
  185. "failed": 0
  186. },
  187. "hits": {
  188. "total": {
  189. "value": 1,
  190. "relation": "eq"
  191. },
  192. "max_score": 1.0,
  193. "hits": [{
  194. "_index": "my-index-000001",
  195. "_id": "1",
  196. "_score": 1.0,
  197. "fields": {
  198. "group" : ["fans"],
  199. "user": [{
  200. "first": ["John"],
  201. "last": ["Smith"]
  202. },
  203. {
  204. "first": ["Alice"],
  205. "last": ["White"]
  206. }
  207. ]
  208. }
  209. }]
  210. }
  211. }
  212. ----
  213. // TESTRESPONSE[s/"took": 2/"took": $body.took/]
  214. // TESTRESPONSE[s/"max_score" : 1.0/"max_score" : $body.hits.max_score/]
  215. // TESTRESPONSE[s/"_score" : 1.0/"_score" : $body.hits.hits.0._score/]
  216. Nested fields will be grouped by their nested paths, no matter the pattern used
  217. to retrieve them. For example, if you query only for the `user.first` field from
  218. the previous example:
  219. [source,console]
  220. --------------------------------------------------
  221. POST my-index-000001/_search
  222. {
  223. "fields": ["user.first"],
  224. "_source": false
  225. }
  226. --------------------------------------------------
  227. // TEST[continued]
  228. The response returns only the user's first name, but still maintains the
  229. structure of the nested `user` array:
  230. [source,console-result]
  231. ----
  232. {
  233. "took": 2,
  234. "timed_out": false,
  235. "_shards": {
  236. "total": 1,
  237. "successful": 1,
  238. "skipped": 0,
  239. "failed": 0
  240. },
  241. "hits": {
  242. "total": {
  243. "value": 1,
  244. "relation": "eq"
  245. },
  246. "max_score": 1.0,
  247. "hits": [{
  248. "_index": "my-index-000001",
  249. "_id": "1",
  250. "_score": 1.0,
  251. "fields": {
  252. "user": [{
  253. "first": ["John"]
  254. },
  255. {
  256. "first": ["Alice"]
  257. }
  258. ]
  259. }
  260. }]
  261. }
  262. }
  263. ----
  264. // TESTRESPONSE[s/"took": 2/"took": $body.took/]
  265. // TESTRESPONSE[s/"max_score" : 1.0/"max_score" : $body.hits.max_score/]
  266. // TESTRESPONSE[s/"_score" : 1.0/"_score" : $body.hits.hits.0._score/]
  267. However, when the `fields` pattern targets the nested `user` field directly, no
  268. values will be returned because the pattern doesn't match any leaf fields.
  269. ====
  270. [discrete]
  271. [[retrieve-unmapped-fields]]
  272. ==== Retrieve unmapped fields
  273. [%collapsible]
  274. ====
  275. By default, the `fields` parameter returns only values of mapped fields.
  276. However, {es} allows storing fields in `_source` that are unmapped, such as
  277. setting <<dynamic-field-mapping,dynamic field mapping>> to `false` or by using
  278. an object field with `enabled: false`. These options disable parsing and
  279. indexing of the object content.
  280. To retrieve unmapped fields in an object from `_source`, use the
  281. `include_unmapped` option in the `fields` section:
  282. [source,console]
  283. ----
  284. PUT my-index-000001
  285. {
  286. "mappings": {
  287. "enabled": false <1>
  288. }
  289. }
  290. PUT my-index-000001/_doc/1?refresh=true
  291. {
  292. "user_id": "kimchy",
  293. "session_data": {
  294. "object": {
  295. "some_field": "some_value"
  296. }
  297. }
  298. }
  299. POST my-index-000001/_search
  300. {
  301. "fields": [
  302. "user_id",
  303. {
  304. "field": "session_data.object.*",
  305. "include_unmapped" : true <2>
  306. }
  307. ],
  308. "_source": false
  309. }
  310. ----
  311. <1> Disable all mappings.
  312. <2> Include unmapped fields matching this field pattern.
  313. The response will contain field results under the `session_data.object.*` path,
  314. even if the fields are unmapped. The `user_id` field is also unmapped, but it
  315. won't be included in the response because `include_unmapped` isn't set to
  316. `true` for that field pattern.
  317. [source,console-result]
  318. ----
  319. {
  320. "took" : 2,
  321. "timed_out" : false,
  322. "_shards" : {
  323. "total" : 1,
  324. "successful" : 1,
  325. "skipped" : 0,
  326. "failed" : 0
  327. },
  328. "hits" : {
  329. "total" : {
  330. "value" : 1,
  331. "relation" : "eq"
  332. },
  333. "max_score" : 1.0,
  334. "hits" : [
  335. {
  336. "_index" : "my-index-000001",
  337. "_id" : "1",
  338. "_score" : 1.0,
  339. "fields" : {
  340. "session_data.object.some_field": [
  341. "some_value"
  342. ]
  343. }
  344. }
  345. ]
  346. }
  347. }
  348. ----
  349. // TESTRESPONSE[s/"took" : 2/"took": $body.took/]
  350. // TESTRESPONSE[s/"max_score" : 1.0/"max_score" : $body.hits.max_score/]
  351. // TESTRESPONSE[s/"_score" : 1.0/"_score" : $body.hits.hits.0._score/]
  352. ====
  353. [discrete]
  354. [[ignored-field-values]]
  355. ==== Ignored field values
  356. [%collapsible]
  357. ====
  358. The `fields` section of the response only returns values that were valid when indexed.
  359. If your search request asks for values from a field that ignored certain values
  360. because they were malformed or too large these values are returned
  361. separately in an `ignored_field_values` section.
  362. In this example we index a document that has a value which is ignored and
  363. not added to the index so is shown separately in search results:
  364. [source,console]
  365. ----
  366. PUT my-index-000001
  367. {
  368. "mappings": {
  369. "properties": {
  370. "my-small" : { "type" : "keyword", "ignore_above": 2 }, <1>
  371. "my-large" : { "type" : "keyword" }
  372. }
  373. }
  374. }
  375. PUT my-index-000001/_doc/1?refresh=true
  376. {
  377. "my-small": ["ok", "bad"], <2>
  378. "my-large": "ok content"
  379. }
  380. POST my-index-000001/_search
  381. {
  382. "fields": ["my-*"],
  383. "_source": false
  384. }
  385. ----
  386. <1> This field has a size restriction
  387. <2> This document field has a value that exceeds the size restriction so is ignored and not indexed
  388. The response will contain ignored field values under the `ignored_field_values` path.
  389. These values are retrieved from the document's original JSON source and are raw so will
  390. not be formatted or treated in any way, unlike the successfully indexed fields which are
  391. returned in the `fields` section.
  392. [source,console-result]
  393. ----
  394. {
  395. "took" : 2,
  396. "timed_out" : false,
  397. "_shards" : {
  398. "total" : 1,
  399. "successful" : 1,
  400. "skipped" : 0,
  401. "failed" : 0
  402. },
  403. "hits" : {
  404. "total" : {
  405. "value" : 1,
  406. "relation" : "eq"
  407. },
  408. "max_score" : 1.0,
  409. "hits" : [
  410. {
  411. "_index" : "my-index-000001",
  412. "_id" : "1",
  413. "_score" : 1.0,
  414. "_ignored" : [ "my-small"],
  415. "fields" : {
  416. "my-large": [
  417. "ok content"
  418. ],
  419. "my-small": [
  420. "ok"
  421. ]
  422. },
  423. "ignored_field_values" : {
  424. "my-small": [
  425. "bad"
  426. ]
  427. }
  428. }
  429. ]
  430. }
  431. }
  432. ----
  433. // TESTRESPONSE[s/"took" : 2/"took": $body.took/]
  434. // TESTRESPONSE[s/"max_score" : 1.0/"max_score" : $body.hits.max_score/]
  435. // TESTRESPONSE[s/"_score" : 1.0/"_score" : $body.hits.hits.0._score/]
  436. ====
  437. [discrete]
  438. [[source-filtering]]
  439. === The `_source` option
  440. You can use the `_source` parameter to select what fields of the source are
  441. returned. This is called _source filtering_.
  442. The following search API request sets the `_source` request body parameter to
  443. `false`. The document source is not included in the response.
  444. [source,console]
  445. ----
  446. GET /_search
  447. {
  448. "_source": false,
  449. "query": {
  450. "match": {
  451. "user.id": "kimchy"
  452. }
  453. }
  454. }
  455. ----
  456. To return only a subset of source fields, specify a wildcard (`*`) pattern in
  457. the `_source` parameter. The following search API request returns the source for
  458. only the `obj` field and its properties.
  459. [source,console]
  460. ----
  461. GET /_search
  462. {
  463. "_source": "obj.*",
  464. "query": {
  465. "match": {
  466. "user.id": "kimchy"
  467. }
  468. }
  469. }
  470. ----
  471. You can also specify an array of wildcard patterns in the `_source` field. The
  472. following search API request returns the source for only the `obj1` and
  473. `obj2` fields and their properties.
  474. [source,console]
  475. ----
  476. GET /_search
  477. {
  478. "_source": [ "obj1.*", "obj2.*" ],
  479. "query": {
  480. "match": {
  481. "user.id": "kimchy"
  482. }
  483. }
  484. }
  485. ----
  486. For finer control, you can specify an object containing arrays of `includes` and
  487. `excludes` patterns in the `_source` parameter.
  488. If the `includes` property is specified, only source fields that match one of
  489. its patterns are returned. You can exclude fields from this subset using the
  490. `excludes` property.
  491. If the `includes` property is not specified, the entire document source is
  492. returned, excluding any fields that match a pattern in the `excludes` property.
  493. The following search API request returns the source for only the `obj1` and
  494. `obj2` fields and their properties, excluding any child `description` fields.
  495. [source,console]
  496. ----
  497. GET /_search
  498. {
  499. "_source": {
  500. "includes": [ "obj1.*", "obj2.*" ],
  501. "excludes": [ "*.description" ]
  502. },
  503. "query": {
  504. "term": {
  505. "user.id": "kimchy"
  506. }
  507. }
  508. }
  509. ----
  510. [discrete]
  511. [[field-retrieval-methods]]
  512. === Other methods of retrieving data
  513. .Using `fields` is typically better
  514. ****
  515. These options are usually not required. Using the `fields` option is typically
  516. the better choice, unless you absolutely need to force loading a stored or
  517. `docvalue_fields`.
  518. ****
  519. A document's `_source` is stored as a single field in Lucene. This structure
  520. means that the whole `_source` object must be loaded and parsed even if you're
  521. only requesting part of it. To avoid this limitation, you can try other options
  522. for loading fields:
  523. * Use the <<docvalue-fields,`docvalue_fields`>>
  524. parameter to get values for selected fields. This can be a good
  525. choice when returning a fairly small number of fields that support doc values,
  526. such as keywords and dates.
  527. * Use the <<request-body-search-stored-fields, `stored_fields`>> parameter to
  528. get the values for specific stored fields (fields that use the
  529. <<mapping-store,`store`>> mapping option).
  530. {es} always attempts to load values from `_source`. This behavior has the same
  531. implications of source filtering where {es} needs to load and parse the entire
  532. `_source` to retrieve just one field.
  533. [discrete]
  534. [[docvalue-fields]]
  535. ==== Doc value fields
  536. You can use the <<docvalue-fields,`docvalue_fields`>> parameter to return
  537. <<doc-values,doc values>> for one or more fields in the search response.
  538. Doc values store the same values as the `_source` but in an on-disk,
  539. column-based structure that's optimized for sorting and aggregations. Since each
  540. field is stored separately, {es} only reads the field values that were requested
  541. and can avoid loading the whole document `_source`.
  542. Doc values are stored for supported fields by default. However, doc values are
  543. not supported for <<text,`text`>> or
  544. {plugins}/mapper-annotated-text-usage.html[`text_annotated`] fields.
  545. The following search request uses the `docvalue_fields` parameter to retrieve
  546. doc values for the `user.id` field, all fields starting with `http.response.`, and the
  547. `@timestamp` field:
  548. [source,console]
  549. ----
  550. GET my-index-000001/_search
  551. {
  552. "query": {
  553. "match": {
  554. "user.id": "kimchy"
  555. }
  556. },
  557. "docvalue_fields": [
  558. "user.id",
  559. "http.response.*", <1>
  560. {
  561. "field": "date",
  562. "format": "epoch_millis" <2>
  563. }
  564. ]
  565. }
  566. ----
  567. // TEST[setup:my_index]
  568. <1> Both full field names and wildcard patterns are accepted.
  569. <2> Using object notation, you can pass a `format` parameter to apply a custom
  570. format for the field's doc values. <<date,Date fields>> support a
  571. <<mapping-date-format,date `format`>>. <<number,Numeric fields>> support a
  572. https://docs.oracle.com/javase/8/docs/api/java/text/DecimalFormat.html[DecimalFormat
  573. pattern]. Other field datatypes do not support the `format` parameter.
  574. TIP: You cannot use the `docvalue_fields` parameter to retrieve doc values for
  575. nested objects. If you specify a nested object, the search returns an empty
  576. array (`[ ]`) for the field. To access nested fields, use the
  577. <<inner-hits, `inner_hits`>> parameter's `docvalue_fields`
  578. property.
  579. [discrete]
  580. [[stored-fields]]
  581. ==== Stored fields
  582. It's also possible to store an individual field's values by using the
  583. <<mapping-store,`store`>> mapping option. You can use the
  584. `stored_fields` parameter to include these stored values in the search response.
  585. WARNING: The `stored_fields` parameter is for fields that are explicitly marked as
  586. stored in the mapping, which is off by default and generally not recommended.
  587. Use <<source-filtering,source filtering>> instead to select
  588. subsets of the original source document to be returned.
  589. Allows to selectively load specific stored fields for each document represented
  590. by a search hit.
  591. [source,console]
  592. --------------------------------------------------
  593. GET /_search
  594. {
  595. "stored_fields" : ["user", "postDate"],
  596. "query" : {
  597. "term" : { "user" : "kimchy" }
  598. }
  599. }
  600. --------------------------------------------------
  601. `*` can be used to load all stored fields from the document.
  602. An empty array will cause only the `_id` and `_type` for each hit to be
  603. returned, for example:
  604. [source,console]
  605. --------------------------------------------------
  606. GET /_search
  607. {
  608. "stored_fields" : [],
  609. "query" : {
  610. "term" : { "user" : "kimchy" }
  611. }
  612. }
  613. --------------------------------------------------
  614. If the requested fields are not stored (`store` mapping set to `false`), they will be ignored.
  615. Stored field values fetched from the document itself are always returned as an array. On the contrary, metadata fields like `_routing` are never returned as an array.
  616. Also only leaf fields can be returned via the `stored_fields` option. If an object field is specified, it will be ignored.
  617. NOTE: On its own, `stored_fields` cannot be used to load fields in nested
  618. objects -- if a field contains a nested object in its path, then no data will
  619. be returned for that stored field. To access nested fields, `stored_fields`
  620. must be used within an <<inner-hits, `inner_hits`>> block.
  621. [discrete]
  622. [[disable-stored-fields]]
  623. ===== Disable stored fields
  624. To disable the stored fields (and metadata fields) entirely use: `_none_`:
  625. [source,console]
  626. --------------------------------------------------
  627. GET /_search
  628. {
  629. "stored_fields": "_none_",
  630. "query" : {
  631. "term" : { "user" : "kimchy" }
  632. }
  633. }
  634. --------------------------------------------------
  635. NOTE: <<source-filtering,`_source`>> and <<request-body-search-version, `version`>> parameters cannot be activated if `_none_` is used.
  636. [discrete]
  637. [[script-fields]]
  638. ==== Script fields
  639. You can use the `script_fields` parameter to retrieve a <<modules-scripting,script
  640. evaluation>> (based on different fields) for each hit. For example:
  641. [source,console]
  642. --------------------------------------------------
  643. GET /_search
  644. {
  645. "query": {
  646. "match_all": {}
  647. },
  648. "script_fields": {
  649. "test1": {
  650. "script": {
  651. "lang": "painless",
  652. "source": "doc['price'].value * 2"
  653. }
  654. },
  655. "test2": {
  656. "script": {
  657. "lang": "painless",
  658. "source": "doc['price'].value * params.factor",
  659. "params": {
  660. "factor": 2.0
  661. }
  662. }
  663. }
  664. }
  665. }
  666. --------------------------------------------------
  667. // TEST[setup:sales]
  668. Script fields can work on fields that are not stored (`price` in
  669. the above case), and allow to return custom values to be returned (the
  670. evaluated value of the script).
  671. Script fields can also access the actual `_source` document and
  672. extract specific elements to be returned from it by using `params['_source']`.
  673. Here is an example:
  674. [source,console]
  675. --------------------------------------------------
  676. GET /_search
  677. {
  678. "query": {
  679. "match_all": {}
  680. },
  681. "script_fields": {
  682. "test1": {
  683. "script": "params['_source']['message']"
  684. }
  685. }
  686. }
  687. --------------------------------------------------
  688. // TEST[setup:my_index]
  689. Note the `_source` keyword here to navigate the json-like model.
  690. It's important to understand the difference between
  691. `doc['my_field'].value` and `params['_source']['my_field']`. The first,
  692. using the doc keyword, will cause the terms for that field to be loaded to
  693. memory (cached), which will result in faster execution, but more memory
  694. consumption. Also, the `doc[...]` notation only allows for simple valued
  695. fields (you can't return a json object from it) and makes sense only for
  696. non-analyzed or single term based fields. However, using `doc` is
  697. still the recommended way to access values from the document, if at all
  698. possible, because `_source` must be loaded and parsed every time it's used.
  699. Using `_source` is very slow.