@@ -189,7 +189,7 @@ Updating or removing a runtime field while a dependent query is running can retu
189189inconsistent results. Each shard might have access to different versions of the
190190script, depending on when the mapping change takes effect.
191191
192- Existing queries or visualizations in {kib} that rely on runtime fields can
192+ WARNING: Existing queries or visualizations in {kib} that rely on runtime fields can
193193fail if you remove or update the field. For example, a bar chart visualization
194194that uses a runtime field of type `ip` will fail if the type is changed
195195to `boolean`, or if the runtime field is removed.
@@ -199,18 +199,17 @@ to `boolean`, or if the runtime field is removed.
199199=== Define runtime fields in a search request
200200You can specify a `runtime_mappings` section in a search request to create
201201runtime fields that exist only as part of the query. You specify a script
202- as part of the `runtime_mappings` section, just as you would if adding a
203- runtime field to the mappings.
202+ as part of the `runtime_mappings` section, just as you would if
203+ << runtime-mapping-fields,adding a runtime field to the mappings>> .
204204
205- Fields defined in the search request take precedence over fields defined with
206- the same name in the index mappings. This flexibility allows you to shadow
207- existing fields and calculate a different value in the search request, without
208- modifying the field itself. If you made a mistake in your index mapping, you
209- can use runtime fields to calculate values that override values in the mapping
210- during the search request.
205+ Defining a runtime field in a search request uses the same format as defining
206+ a runtime field in the index mapping. Just copy the field definition from
207+ the `runtime_mappings` in the search request to the `runtime` section of the
208+ index mapping.
211209
212- In the following request, the values for the `day_of_week` field are calculated
213- dynamically, and only within the context of this search request:
210+ The following search request adds a `day_of_week` field to the
211+ `runtime_mappings` section. The field values will be calculated dynamically,
212+ and only within the context of this search request:
214213
215214[source,console]
216215----
@@ -235,11 +234,155 @@ GET my-index/_search
235234----
236235//TEST[continued]
237236
238- Defining a runtime field in a search request uses the same format as defining
239- a runtime field in the index mapping. That consistency means you can promote a
240- runtime field from a search request to the index mapping by moving the field
241- definition from `runtime_mappings` in the search request to the `runtime`
242- section of the index mapping.
237+ [[runtime-search-request-examples]]
238+ [discrete]
239+ === Create runtime fields that use other runtime fields
240+ You can even define runtime fields in a search request that return values from
241+ other runtime fields. For example, let's say you bulk index some sensor data:
242+
243+ [source,console]
244+ ----
245+ POST my-index/_bulk?refresh=true
246+ {"index":{}}
247+ {"@timestamp":1516729294000,"model_number":"QVKC92Q","measures":{"voltage":"5.2","start": "300","end":"8675309"}}
248+ {"index":{}}
249+ {"@timestamp":1516642894000,"model_number":"QVKC92Q","measures":{"voltage":"5.8","start": "300","end":"8675309"}}
250+ {"index":{}}
251+ {"@timestamp":1516556494000,"model_number":"QVKC92Q","measures":{"voltage":"5.1","start": "300","end":"8675309"}}
252+ {"index":{}}
253+ {"@timestamp":1516470094000,"model_number":"QVKC92Q","measures":{"voltage":"5.6","start": "300","end":"8675309"}}
254+ {"index":{}}
255+ {"@timestamp":1516383694000,"model_number":"HG537PU","measures":{"voltage":"4.2","start": "400","end":"8625309"}}
256+ {"index":{}}
257+ {"@timestamp":1516297294000,"model_number":"HG537PU","measures":{"voltage":"4.0","start": "400","end":"8625309"}}
258+ ----
259+
260+ You realize after indexing that your numeric data was mapped as type `text`.
261+ You want to aggregate on the `measures.start` and `measures.end` fields, but
262+ the aggregation fails because you can't aggregate on fields of type `text`.
263+ Runtime fields to the rescue! You can add runtime fields with the same name as
264+ your indexed fields and modify the data type:
265+
266+ [source,console]
267+ ----
268+ PUT my-index/_mapping
269+ {
270+ "runtime": {
271+ "measures.start": {
272+ "type": "long"
273+ },
274+ "measures.end": {
275+ "type": "long"
276+ }
277+ }
278+ }
279+ ----
280+ // TEST[continued]
281+
282+ Runtime fields take precedence over fields defined with the same name in the
283+ index mappings. This flexibility allows you to shadow existing fields and
284+ calculate a different value, without modifying the field itself. If you made a
285+ mistake in your index mapping, you can use runtime fields to calculate values
286+ that <<runtime-override-values,override values>> in the mapping during the
287+ search request.
288+
289+ Now, you can easily run an
290+ <<search-aggregations-metrics-avg-aggregation,average aggregation>> on the
291+ `measures.start` and `measures.end` fields:
292+
293+ [source,console]
294+ ----
295+ GET my-index/_search
296+ {
297+ "aggs": {
298+ "avg_start": {
299+ "avg": {
300+ "field": "measures.start"
301+ }
302+ },
303+ "avg_end": {
304+ "avg": {
305+ "field": "measures.end"
306+ }
307+ }
308+ }
309+ }
310+ ----
311+ // TEST[continued]
312+ // TEST[s/_search/_search\?filter_path=aggregations/]
313+
314+ The response includes the aggregation results without changing the values for
315+ the underlying data:
316+
317+ [source,console-result]
318+ ----
319+ {
320+ "aggregations" : {
321+ "avg_start" : {
322+ "value" : 333.3333333333333
323+ },
324+ "avg_end" : {
325+ "value" : 8658642.333333334
326+ }
327+ }
328+ }
329+ ----
330+
331+ Further, you can define a runtime field as part of a search query that
332+ calculates a value, and then run a
333+ <<search-aggregations-metrics-stats-aggregation,stats aggregation>> on that
334+ field _in the same query_.
335+
336+ The `duration` runtime field doesn't exist in the index mapping, but we can
337+ still search and aggregate on that field. The following query returns the
338+ calculated value for the `duration` field and runs a stats aggregation to
339+ compute statistics over numeric values extracted from the aggregated documents.
340+
341+ [source,console]
342+ ----
343+ GET my-index/_search
344+ {
345+ "runtime_mappings": {
346+ "duration": {
347+ "type": "long",
348+ "script": {
349+ "source": """
350+ emit(doc['measures.end'].value - doc['measures.start'].value);
351+ """
352+ }
353+ }
354+ },
355+ "aggs": {
356+ "duration_stats": {
357+ "stats": {
358+ "field": "duration"
359+ }
360+ }
361+ }
362+ }
363+ ----
364+ // TEST[continued]
365+ // TEST[s/_search/_search\?filter_path=aggregations/]
366+
367+ Even though the `duration` runtime field only exists in the context of a search
368+ query, you can search and aggregate on that field. This flexibility is
369+ incredibly powerful, enabling you to rectify mistakes in your index mappings
370+ and dynamically complete calculations all within a single search request.
371+
372+ [source,console-result]
373+ ----
374+ {
375+ "aggregations" : {
376+ "duration_stats" : {
377+ "count" : 6,
378+ "min" : 8624909.0,
379+ "max" : 8675009.0,
380+ "avg" : 8658309.0,
381+ "sum" : 5.1949854E7
382+ }
383+ }
384+ }
385+ ----
243386
244387[[runtime-override-values]]
245388=== Override field values at query time
0 commit comments