runtime.asciidoc 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661
  1. [[runtime]]
  2. == Runtime fields
  3. Typically, you index data into {es} to promote faster search. However, indexing
  4. can be slow and requires more disk space, and you have to reindex your data to
  5. add fields to existing documents. With _runtime fields_, you can add
  6. fields to documents already indexed to {es} without reindexing your data.
  7. You access runtime fields from the search API like any other field, and {es}
  8. sees runtime fields no differently.
  9. [discrete]
  10. [[runtime-benefits]]
  11. === Benefits
  12. Because runtime fields aren't indexed, adding a runtime field doesn't increase
  13. the index size. You define runtime fields directly in the index mapping, saving
  14. storage costs and increasing ingestion speed. You can more quickly ingest
  15. data into the Elastic Stack and access it right away. When you define a runtime
  16. field, you can immediately use it in search requests, aggregations, filtering,
  17. and sorting.
  18. If you make a runtime field an indexed field, you don't need to modify any
  19. queries that refer to the runtime field. Better yet, you can refer to some
  20. indices where the field is a runtime field, and other indices where the field
  21. is an indexed field. You have the flexibility to choose which fields to index
  22. and which ones to keep as runtime fields.
  23. [discrete]
  24. [[runtime-use-cases]]
  25. === Use cases
  26. Runtime fields are useful when working with log data
  27. (see <<runtime-examples,examples>>), especially when you're unsure about the
  28. data structure. Your search speed decreases, but your index size is much
  29. smaller and you can more quickly process logs without having to index them.
  30. Runtime fields are especially useful in the following contexts:
  31. * Adding fields to documents that are already indexed without having to reindex
  32. data
  33. * Immediately begin working on a new data stream without fully understanding
  34. the data it contains
  35. * Shadowing an indexed field with a runtime field to fix a mistake after
  36. indexing documents
  37. * Defining fields that are only relevant for a particular context (such as a
  38. visualization in {kib}) without influencing the underlying schema
  39. [discrete]
  40. [[runtime-compromises]]
  41. === Compromises
  42. Runtime fields use less disk space and provide flexibility in how you access
  43. your data, but can impact search performance based on the computation defined in
  44. the runtime script.
  45. To balance search performance and flexibility, index fields that you'll
  46. commonly search for and filter on, such as a timestamp. {es} automatically uses
  47. these indexed fields first when running a query, resulting in a fast response
  48. time. You can then use runtime fields to limit the number of fields that {es}
  49. needs to calculate values for. Using indexed fields in tandem with runtime
  50. fields provides flexibility in the data that you index and how you define
  51. queries for other fields.
  52. Use the <<async-search,asynchronous search API>> to run searches that include
  53. runtime fields. This method of search helps to offset the performance impacts
  54. of computing values for runtime fields in each document containing that field.
  55. If the query can't return the result set synchronously, you'll get results
  56. asynchronously as they become available.
  57. IMPORTANT: Queries against runtime fields are considered expensive. If
  58. <<query-dsl-allow-expensive-queries,`search.allow_expensive_queries`>> is set
  59. to `false`, expensive queries are not allowed and {es} will reject any queries
  60. against runtime fields.
  61. [[runtime-mapping-fields]]
  62. === Mapping a runtime field
  63. You map runtime fields by adding a `runtime` section under the mapping
  64. definition and defining
  65. <<modules-scripting-using,a Painless script>>. This script has access to the
  66. entire context of a document, including the original `_source` and any mapped
  67. fields plus their values. At search time, the script runs and generates values
  68. for each scripted field that is required for the query.
  69. NOTE: You can define a runtime field in the mapping definition without a
  70. script. If you define a runtime field without a script, {es} evaluates the
  71. field at search time, looks at each document containing that field, retrieves
  72. the `_source`, and returns a value if one exists.
  73. Runtime fields are similar to the <<script-fields,`script_fields`>> parameter
  74. of the `_search` request, but also make the script results available anywhere
  75. in a search request.
  76. The script in the following request extracts the day of the week from the
  77. `@timestamp` field, which is defined as a `date` type:
  78. [source,console]
  79. ----
  80. PUT /my-index
  81. {
  82. "mappings": {
  83. "runtime": { <1>
  84. "day_of_week": {
  85. "type": "keyword", <2>
  86. "script": { <3>
  87. "source": "emit(doc['@timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ROOT))"
  88. }
  89. }
  90. },
  91. "properties": {
  92. "timestamp": {"type": "date"}
  93. }
  94. }
  95. }
  96. ----
  97. <1> Runtime fields are defined in the `runtime` section of the mapping
  98. definition.
  99. <2> Each runtime field has its own field type, just like any other field.
  100. <3> The script defines the evaluation to calculate at search time.
  101. The `runtime` section supports `boolean`, `date`, `double`, `geo_point`, `ip`,
  102. `keyword`, and `long` data types. Runtime fields with a `type` of `date` can
  103. accept the <<mapping-date-format,`format`>> parameter exactly as the `date`
  104. field type.
  105. [[runtime-updating-scripts]]
  106. .Updating runtime scripts
  107. ****
  108. Updating a script while a dependent query is running can return
  109. inconsistent results. Each shard might have access to different versions of the
  110. script, depending on when the mapping change takes effect.
  111. Existing queries or visualizations in {kib} that rely on runtime fields can
  112. fail if you change the field type. For example, a bar chart visualization
  113. that uses a runtime field of type `ip` will fail if the type is changed
  114. to `boolean`.
  115. ****
  116. [[runtime-search-request]]
  117. === Defining runtime fields in a search request
  118. You can specify a `runtime_mappings` section in a search request to create
  119. runtime fields that exist only as part of the query. You specify a script
  120. as part of the `runtime_mappings` section, just as you would if adding a
  121. runtime field to the mappings.
  122. Fields defined in the search request take precedence over fields defined with
  123. the same name in the index mappings. This flexibility allows you to shadow
  124. existing fields and calculate a different value in the search request, without
  125. modifying the field itself. If you made a mistake in your index mapping, you
  126. can use runtime fields to calculate values that override values in the mapping
  127. during the search request.
  128. In the following request, the values for the `day_of_week` field are calculated
  129. dynamically, and only within the context of this search request:
  130. [source,console]
  131. ----
  132. GET my-index/_search
  133. {
  134. "runtime_mappings": {
  135. "day_of_week": {
  136. "type": "keyword",
  137. "script": {
  138. "source": "emit(doc['@timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ROOT))"
  139. }
  140. }
  141. },
  142. "aggs": {
  143. "day_of_week": {
  144. "terms": {
  145. "field": "day_of_week"
  146. }
  147. }
  148. }
  149. }
  150. ----
  151. // TEST[continued]
  152. Defining a runtime field in a search request uses the same format as defining
  153. a runtime field in the index mapping. That consistency means you can promote a
  154. runtime field from a search request to the index mapping by moving the field
  155. definition from `runtime_mappings` in the search request to the `runtime`
  156. section of the index mapping.
  157. [[runtime-shadowing-fields]]
  158. === Shadowing fields
  159. If you create a runtime field with the same name as a field that
  160. already exists in the mapping, the runtime field shadows the mapped field. At
  161. search time, {es} evaluates the runtime field, calculates a value based on the
  162. script, and returns the value as part of the query. Because the runtime field
  163. shadows the mapped field, you can modify the value returned in search without
  164. modifying the mapped field.
  165. For example, let's say you indexed the following documents into `my-index`:
  166. [source,console]
  167. ----
  168. POST my-index/_bulk?refresh=true
  169. {"index":{}}
  170. {"timestamp":1516729294000,"model_number":"QVKC92Q","measures":{"voltage":5.2}}
  171. {"index":{}}
  172. {"timestamp":1516642894000,"model_number":"QVKC92Q","measures":{"voltage":5.8}}
  173. {"index":{}}
  174. {"timestamp":1516556494000,"model_number":"QVKC92Q","measures":{"voltage":5.1}}
  175. {"index":{}}
  176. {"timestamp":1516470094000,"model_number":"QVKC92Q","measures":{"voltage":5.6}}
  177. {"index":{}}
  178. {"timestamp":1516383694000,"model_number":"HG537PU","measures":{"voltage":4.2}}
  179. {"index":{}}
  180. {"timestamp":1516297294000,"model_number":"HG537PU","measures":{"voltage":4.0}}
  181. ----
  182. You later realize that the `HG537PU` sensors aren't reporting their true
  183. voltage. The indexed values are supposed to be 1.7 times higher than
  184. the reported values! Instead of reindexing your data, you can define a script in
  185. the `runtime_mappings` section of the `_search` request to shadow the `voltage`
  186. field and calculate a new value at search time.
  187. If you search for documents where the model number matches `HG537PU`:
  188. [source,console]
  189. ----
  190. GET my-index/_search
  191. {
  192. "query": {
  193. "match": {
  194. "model_number": "HG537PU"
  195. }
  196. }
  197. }
  198. ----
  199. //TEST[continued]
  200. The response includes indexed values for documents matching model number
  201. `HG537PU`:
  202. [source,console-result]
  203. ----
  204. {
  205. ...
  206. "hits" : {
  207. "total" : {
  208. "value" : 2,
  209. "relation" : "eq"
  210. },
  211. "max_score" : 1.0296195,
  212. "hits" : [
  213. {
  214. "_index" : "my-index",
  215. "_id" : "F1BeSXYBg_szTodcYCmk",
  216. "_score" : 1.0296195,
  217. "_source" : {
  218. "timestamp" : 1516383694000,
  219. "model_number" : "HG537PU",
  220. "measures" : {
  221. "voltage" : 4.2
  222. }
  223. }
  224. },
  225. {
  226. "_index" : "my-index",
  227. "_id" : "l02aSXYBkpNf6QRDO62Q",
  228. "_score" : 1.0296195,
  229. "_source" : {
  230. "timestamp" : 1516297294000,
  231. "model_number" : "HG537PU",
  232. "measures" : {
  233. "voltage" : 4.0
  234. }
  235. }
  236. }
  237. ]
  238. }
  239. }
  240. ----
  241. // TESTRESPONSE[s/\.\.\./"took" : $body.took,"timed_out" : $body.timed_out,"_shards" : $body._shards,/]
  242. // TESTRESPONSE[s/"_id" : "F1BeSXYBg_szTodcYCmk"/"_id": $body.hits.hits.0._id/]
  243. // TESTRESPONSE[s/"_id" : "l02aSXYBkpNf6QRDO62Q"/"_id": $body.hits.hits.1._id/]
  244. The following request defines a runtime field where the script evaluates the
  245. `model_number` field where the value is `HG537PU`. For each match, the script
  246. multiplies the value for the `voltage` field by `1.7`.
  247. Using the <<search-fields,`fields`>> parameter on the `_search` API, you can
  248. retrieve the value that the script calculates for the `measures.voltage` field
  249. for documents matching the search request:
  250. [source,console]
  251. ----
  252. POST my-index/_search
  253. {
  254. "runtime_mappings": {
  255. "measures.voltage": {
  256. "type": "double",
  257. "script": {
  258. "source":
  259. """if (doc['model_number.keyword'].value.equals('HG537PU'))
  260. {emit(1.7 * params._source['measures']['voltage']);}
  261. else{emit(params._source['measures']['voltage']);}"""
  262. }
  263. }
  264. },
  265. "query": {
  266. "match": {
  267. "model_number": "HG537PU"
  268. }
  269. },
  270. "fields": ["measures.voltage"]
  271. }
  272. ----
  273. //TEST[continued]
  274. Looking at the response, the calculated values for `measures.voltage` on each
  275. result are `7.14` and `6.8`. That's more like it! The runtime field calculated
  276. this value as part of the search request without modifying the mapped value,
  277. which still returns in the response:
  278. [source,console-result]
  279. ----
  280. {
  281. ...
  282. "hits" : {
  283. "total" : {
  284. "value" : 2,
  285. "relation" : "eq"
  286. },
  287. "max_score" : 1.0296195,
  288. "hits" : [
  289. {
  290. "_index" : "my-index",
  291. "_id" : "F1BeSXYBg_szTodcYCmk",
  292. "_score" : 1.0296195,
  293. "_source" : {
  294. "timestamp" : 1516383694000,
  295. "model_number" : "HG537PU",
  296. "measures" : {
  297. "voltage" : 4.2
  298. }
  299. },
  300. "fields" : {
  301. "measures.voltage" : [
  302. 7.14
  303. ]
  304. }
  305. },
  306. {
  307. "_index" : "my-index",
  308. "_id" : "l02aSXYBkpNf6QRDO62Q",
  309. "_score" : 1.0296195,
  310. "_source" : {
  311. "timestamp" : 1516297294000,
  312. "model_number" : "HG537PU",
  313. "measures" : {
  314. "voltage" : 4.0
  315. }
  316. },
  317. "fields" : {
  318. "measures.voltage" : [
  319. 6.8
  320. ]
  321. }
  322. }
  323. ]
  324. }
  325. }
  326. ----
  327. // TESTRESPONSE[s/\.\.\./"took" : $body.took,"timed_out" : $body.timed_out,"_shards" : $body._shards,/]
  328. // TESTRESPONSE[s/"_id" : "F1BeSXYBg_szTodcYCmk"/"_id": $body.hits.hits.0._id/]
  329. // TESTRESPONSE[s/"_id" : "l02aSXYBkpNf6QRDO62Q"/"_id": $body.hits.hits.1._id/]
  330. [[runtime-retrieving-fields]]
  331. === Retrieving a runtime field
  332. Use the <<search-fields,`fields`>> parameter on the `_search` API to retrieve
  333. the values of runtime fields. Runtime fields won't display in `_source`, but
  334. the `fields` API works for all fields, even those that were not sent as part of
  335. the original `_source`.
  336. The following request uses the search API to retrieve the `day_of_week` field
  337. that <<runtime-mapping-fields,this previous request>> defined as a runtime field
  338. in the mapping. The value for the `day_of_week` field is calculated dynamically
  339. at search time based on the evaluation of the defined script.
  340. [source,console]
  341. ----
  342. GET my-index/_search
  343. {
  344. "fields": [
  345. "@timestamp",
  346. "day_of_week"
  347. ],
  348. "_source": false
  349. }
  350. ----
  351. // TEST[continued]
  352. [[runtime-examples]]
  353. === Runtime fields examples
  354. Consider a large set of log data that you want to extract fields from.
  355. Indexing the data is time consuming and uses a lot of disk space, and you just
  356. want to explore the data structure without committing to a schema up front.
  357. You know that your log data contains specific fields that you want to extract.
  358. By using runtime fields, you can define scripts to calculate values at search
  359. time for these fields.
  360. You can start with a simple example by adding the `@timestamp` and `message`
  361. fields to the `my-index` mapping. To remain flexible, use `wildcard` as the
  362. field type for `message`:
  363. [source,console]
  364. ----
  365. PUT /my-index/
  366. {
  367. "mappings": {
  368. "properties": {
  369. "@timestamp": {
  370. "format": "strict_date_optional_time||epoch_second",
  371. "type": "date"
  372. },
  373. "message": {
  374. "type": "wildcard"
  375. }
  376. }
  377. }
  378. }
  379. ----
  380. After mapping the fields you want to retrieve, index a few records from
  381. your log data into {es}. The following request uses the <<docs-bulk,bulk API>>
  382. to index raw log data into `my-index`. Instead of indexing all of your log
  383. data, you can use a small sample to experiment with runtime fields.
  384. [source,console]
  385. ----
  386. POST /my-index/_bulk?refresh
  387. { "index": {}}
  388. { "@timestamp": "2020-06-21T15:00:01-05:00", "message" : "211.11.9.0 - - [2020-06-21T15:00:01-05:00] \"GET /english/index.html HTTP/1.0\" 304 0"}
  389. { "index": {}}
  390. { "@timestamp": "2020-06-21T15:00:01-05:00", "message" : "211.11.9.0 - - [2020-06-21T15:00:01-05:00] \"GET /english/index.html HTTP/1.0\" 304 0"}
  391. { "index": {}}
  392. { "@timestamp": "2020-04-30T14:30:17-05:00", "message" : "40.135.0.0 - - [2020-04-30T14:30:17-05:00] \"GET /images/hm_bg.jpg HTTP/1.0\" 200 24736"}
  393. { "index": {}}
  394. { "@timestamp": "2020-04-30T14:30:53-05:00", "message" : "232.0.0.0 - - [2020-04-30T14:30:53-05:00] \"GET /images/hm_bg.jpg HTTP/1.0\" 200 24736"}
  395. { "index": {}}
  396. { "@timestamp": "2020-04-30T14:31:12-05:00", "message" : "26.1.0.0 - - [2020-04-30T14:31:12-05:00] \"GET /images/hm_bg.jpg HTTP/1.0\" 200 24736"}
  397. { "index": {}}
  398. { "@timestamp": "2020-04-30T14:31:19-05:00", "message" : "247.37.0.0 - - [2020-04-30T14:31:19-05:00] \"GET /french/splash_inet.html HTTP/1.0\" 200 3781"}
  399. { "index": {}}
  400. { "@timestamp": "2020-04-30T14:31:27-05:00", "message" : "252.0.0.0 - - [2020-04-30T14:31:27-05:00] \"GET /images/hm_bg.jpg HTTP/1.0\" 200 24736"}
  401. { "index": {}}
  402. { "@timestamp": "2020-04-30T14:31:29-05:00", "message" : "247.37.0.0 - - [2020-04-30T14:31:29-05:00] \"GET /images/hm_brdl.gif HTTP/1.0\" 304 0"}
  403. { "index": {}}
  404. { "@timestamp": "2020-04-30T14:31:29-05:00", "message" : "247.37.0.0 - - [2020-04-30T14:31:29-05:00] \"GET /images/hm_arw.gif HTTP/1.0\" 304 0"}
  405. { "index": {}}
  406. { "@timestamp": "2020-04-30T14:31:32-05:00", "message" : "247.37.0.0 - - [2020-04-30T14:31:32-05:00] \"GET /images/nav_bg_top.gif HTTP/1.0\" 200 929"}
  407. { "index": {}}
  408. { "@timestamp": "2020-04-30T14:31:43-05:00", "message" : "247.37.0.0 - - [2020-04-30T14:31:43-05:00] \"GET /french/images/nav_venue_off.gif HTTP/1.0\" 304 0"}
  409. ----
  410. // TEST[continued]
  411. At this point, you can view how {es} stores your raw data.
  412. [source,console]
  413. ----
  414. GET /my-index
  415. ----
  416. // TEST[continued]
  417. The mapping contains two fields: `@timestamp` and `message`.
  418. [source,console-result]
  419. ----
  420. {
  421. "my-index" : {
  422. "aliases" : { },
  423. "mappings" : {
  424. "properties" : {
  425. "@timestamp" : {
  426. "type" : "date",
  427. "format" : "strict_date_optional_time||epoch_second"
  428. },
  429. "message" : {
  430. "type" : "wildcard"
  431. }
  432. }
  433. },
  434. ...
  435. }
  436. }
  437. ----
  438. // TESTRESPONSE[s/\.\.\./"settings": $body.my-index.settings/]
  439. If you want to retrieve results that include `clientip`, you can add that field
  440. as a runtime field in the mapping. The runtime script operates on the `clientip`
  441. field at runtime to calculate values for that field.
  442. [source,console]
  443. ----
  444. PUT /my-index/_mapping
  445. {
  446. "runtime": {
  447. "clientip": {
  448. "type": "ip",
  449. "script" : {
  450. "source" : "String m = doc[\"message\"].value; int end = m.indexOf(\" \"); emit(m.substring(0, end));"
  451. }
  452. }
  453. }
  454. }
  455. ----
  456. // TEST[continued]
  457. Using the `clientip` runtime field, you can define a simple query to run a
  458. search for a specific IP address and return all related fields.
  459. [source,console]
  460. ----
  461. GET my-index/_search
  462. {
  463. "size": 1,
  464. "query": {
  465. "match": {
  466. "clientip": "211.11.9.0"
  467. }
  468. },
  469. "fields" : ["*"]
  470. }
  471. ----
  472. // TEST[continued]
  473. The API returns the following result. Without building your data structure in
  474. advance, you can search and explore your data in meaningful ways to experiment
  475. and determine which fields to index.
  476. [source,console-result]
  477. ----
  478. {
  479. ...
  480. "hits" : {
  481. "total" : {
  482. "value" : 2,
  483. "relation" : "eq"
  484. },
  485. "max_score" : 1.0,
  486. "hits" : [
  487. {
  488. "_index" : "my-index",
  489. "_id" : "oWs5KXYB-XyJbifr9mrz",
  490. "_score" : 1.0,
  491. "_source" : {
  492. "@timestamp" : "2020-06-21T15:00:01-05:00",
  493. "message" : "211.11.9.0 - - [2020-06-21T15:00:01-05:00] \"GET /english/index.html HTTP/1.0\" 304 0"
  494. },
  495. "fields" : {
  496. "@timestamp" : [
  497. "2020-06-21T20:00:01.000Z"
  498. ],
  499. "clientip" : [
  500. "211.11.9.0"
  501. ],
  502. "message" : [
  503. "211.11.9.0 - - [2020-06-21T15:00:01-05:00] \"GET /english/index.html HTTP/1.0\" 304 0"
  504. ]
  505. }
  506. }
  507. ]
  508. }
  509. }
  510. ----
  511. // TESTRESPONSE[s/\.\.\./"took" : $body.took,"timed_out" : $body.timed_out,"_shards" : $body._shards,/]
  512. // TESTRESPONSE[s/"_id" : "oWs5KXYB-XyJbifr9mrz"/"_id": $body.hits.hits.0._id/]
  513. You can add the `day_of_week` field to the mapping using the request from
  514. <<runtime-mapping-fields,mapping a runtime field>>:
  515. [source,console]
  516. ----
  517. PUT /my-index/_mapping
  518. {
  519. "runtime": {
  520. "day_of_week": {
  521. "type": "keyword",
  522. "script": {
  523. "source": "emit(doc['@timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ROOT))"
  524. }
  525. }
  526. },
  527. "properties": {
  528. "timestamp": {
  529. "type": "date"
  530. }
  531. }
  532. }
  533. ----
  534. // TEST[continued]
  535. Then, you can re-run the previous search request and also retrieve the day of
  536. the week based on the `@timestamp` field:
  537. [source,console]
  538. ----
  539. GET my-index/_search
  540. {
  541. "size": 1,
  542. "query": {
  543. "match": {
  544. "clientip": "211.11.9.0"
  545. }
  546. },
  547. "fields" : ["*"]
  548. }
  549. ----
  550. // TEST[continued]
  551. The value for this field is calculated dynamically at runtime without
  552. reindexing the document or adding the `day_of_week` field. This flexibility
  553. allows you to modify the mapping without changing any field values.
  554. [source,console-result]
  555. ----
  556. {
  557. ...
  558. "hits" : {
  559. "total" : {
  560. "value" : 2,
  561. "relation" : "eq"
  562. },
  563. "max_score" : 1.0,
  564. "hits" : [
  565. {
  566. "_index" : "my-index",
  567. "_id" : "oWs5KXYB-XyJbifr9mrz",
  568. "_score" : 1.0,
  569. "_source" : {
  570. "@timestamp" : "2020-06-21T15:00:01-05:00",
  571. "message" : "211.11.9.0 - - [2020-06-21T15:00:01-05:00] \"GET /english/index.html HTTP/1.0\" 304 0"
  572. },
  573. "fields" : {
  574. "@timestamp" : [
  575. "2020-06-21T20:00:01.000Z"
  576. ],
  577. "clientip" : [
  578. "211.11.9.0"
  579. ],
  580. "message" : [
  581. "211.11.9.0 - - [2020-06-21T15:00:01-05:00] \"GET /english/index.html HTTP/1.0\" 304 0"
  582. ],
  583. "day_of_week" : [
  584. "Sunday" <1>
  585. ]
  586. }
  587. }
  588. ]
  589. }
  590. }
  591. ----
  592. // TESTRESPONSE[s/\.\.\./"took" : $body.took,"timed_out" : $body.timed_out,"_shards" : $body._shards,/]
  593. // TESTRESPONSE[s/"_id" : "oWs5KXYB-XyJbifr9mrz"/"_id": $body.hits.hits.0._id/]
  594. // TESTRESPONSE[s/"day_of_week" : \[\n\s+"Sunday"\n\s\]/"day_of_week": $body.hits.hits.0.fields.day_of_week/]
  595. <1> This value was calculated at search time using the runtime script defined
  596. in the mapping.