﻿---
title: Scripted fields
description: Scripted fields compute values at query time from a Kibana data view. Deprecated in favor of runtime fields and ES|QL.
url: https://www.elastic.co/elastic/docs-builder/docs/4120/explore-analyze/find-and-organize/data-views/scripted-fields
products:
  - Kibana
applies_to:
  - Elastic Cloud Serverless: Unavailable
  - Elastic Stack: Deprecated
---

# Scripted fields
<admonition title="Deprecated in 7.13, creation removed in 9.0.">
  Use [runtime fields](https://www.elastic.co/elastic/docs-builder/docs/4120/explore-analyze/find-and-organize/data-views/runtime-fields) instead of scripted fields. Runtime fields support Painless scripting and provide greater flexibility. You can also use the [Elasticsearch Query Language (ES|QL)](https://docs-v3-preview.elastic.dev/elastic/docs-builder/docs/4120/reference/query-languages/esql) to compute values directly at query time.
</admonition>

Scripted fields compute data on the fly from your Elasticsearch indices. The values appear in **Discover** as part of the document data. You can use scripted fields in visualizations, query them with the [Kibana query language](https://www.elastic.co/elastic/docs-builder/docs/4120/explore-analyze/query-filter/languages/kql), and filter them in the filter bar. The values are computed at query time, so they aren't indexed and can't be searched using the Kibana default query language.
Computing scripted fields at query time can be resource intensive and can slow Kibana. Kibana doesn't validate scripted fields. If a script contains errors, you get exceptions when you view the generated data.
When you define a scripted field in Kibana, you have a choice of the [Lucene expressions](https://www.elastic.co/elastic/docs-builder/docs/4120/explore-analyze/scripting/modules-scripting-expression) or the [Painless](https://www.elastic.co/elastic/docs-builder/docs/4120/explore-analyze/scripting/modules-scripting-painless) scripting language.
You can reference any single value numeric field in your expressions, for example:
```
doc['field_name'].value
```

For more information on scripted fields and additional examples, refer to [Using Painless in Kibana scripted fields](https://www.elastic.co/blog/using-painless-kibana-scripted-fields)

## Migrate to runtime fields or ES|QL queries

The following examples migrate a scripted field called `computed_values` on the Kibana Sample Data Logs data view to a runtime field and to an ES|QL query.

### Scripted field

In the scripted field example, variables track every value the script needs to access or return. Scripted fields can return only a single value, so the variables must be returned together as an array at the end of the script.
```text
def hour_of_day = $('@timestamp', ZonedDateTime.parse('1970-01-01T00:00:00Z')).getHour();
def time_of_day = '';

if (hour_of_day >= 22 || hour_of_day < 5)
  time_of_day = 'Night';
else if (hour_of_day < 12)
  time_of_day = 'Morning';
else if (hour_of_day < 18)
  time_of_day = 'Afternoon';
else
  time_of_day = 'Evening';

def response_int = Integer.parseInt($('response.keyword', '200'));
def response_category = '';

if (response_int < 200)
  response_category = 'Informational';
else if (response_int < 300)
  response_category = 'Successful';
else if (response_int < 400)
  response_category = 'Redirection';
else if (response_int < 500)
  response_category = 'Client Error';
else
  response_category = 'Server Error';

return [time_of_day, response_category];
```


### Runtime field

Unlike scripted fields, runtime fields don't need to return a single value. They can emit values at any point in the script. Kibana combines those values and returns them as a multi-value field. That removes the need to manage an array of values yourself.
```text
def hour_of_day = $('@timestamp', ZonedDateTime.parse('1970-01-01T00:00:00Z')).getHour();

if (hour_of_day >= 22 || hour_of_day < 5)
  emit('Night');
else if (hour_of_day < 12)
  emit('Morning');
else if (hour_of_day < 18)
  emit('Afternoon');
else
  emit('Evening');

def response_int = Integer.parseInt($('response.keyword', '200'));

if (response_int < 200)
  emit('Informational');
else if (response_int < 300)
  emit('Successful');
else if (response_int < 400)
  emit('Redirection');
else if (response_int < 500)
  emit('Client Error');
else
  emit('Server Error');
```


### ES|QL query

Alternatively, you can use ES|QL to compute the values you need at query time, without managing a data view. ES|QL can compute multiple field values in a single query, use those values with its commands and functions, and aggregate against them. That approach fits one-off queries and real-time analysis.
```esql
FROM kibana_sample_data_logs
  | EVAL hour_of_day = DATE_EXTRACT("HOUR_OF_DAY", @timestamp)
  | EVAL time_of_day = CASE(
      hour_of_day >= 22 OR hour_of_day < 5, "Night",
      hour_of_day < 12, "Morning",
      hour_of_day < 18, "Afternoon",
      "Evening"
    )
  | EVAL response_int = TO_INTEGER(response)
  | EVAL response_category = CASE(
      response_int < 200, "Informational",
      response_int < 300, "Successful",
      response_int < 400, "Redirection",
      response_int < 500, "Client Error",
      "Server Error"
    )
  | EVAL computed_values = MV_APPEND(time_of_day, response_category)
  | DROP hour_of_day, time_of_day, response_int, response_category
```


## Manage existing scripted fields

<warning>
  The ability to create new scripted fields has been removed from the **Data Views** management page in 9.0. Existing scripted fields can still be edited or deleted, and the creation UI can be accessed by navigating directly to `/app/management/kibana/dataViews/dataView/{{dataViewId}}/create-field`, but we recommend migrating to runtime fields or ES|QL queries instead to prepare for removal.
</warning>


### Before you begin

You need a role with the **Data View Management** Kibana privilege and the `view_index_metadata` Elasticsearch privilege. Refer to [Defining roles](https://www.elastic.co/elastic/docs-builder/docs/4120/deploy-manage/users-roles/cluster-or-deployment-auth/defining-roles).

### Edit or delete a scripted field

1. Go to the **Data Views** management page using the navigation menu or the [global search field](https://www.elastic.co/elastic/docs-builder/docs/4120/explore-analyze/find-and-organize/find-apps-and-objects).
2. Select the data view that contains the scripted field you want to manage.
3. Select the **Scripted fields** tab, then open the scripted field edit options or delete the scripted field.

Your change takes effect immediately anywhere the data view is used.
For more information about scripted fields in Elasticsearch, refer to [Scripting](https://www.elastic.co/elastic/docs-builder/docs/4120/explore-analyze/scripting).

## Related pages

- [Data views](https://www.elastic.co/elastic/docs-builder/docs/4120/explore-analyze/find-and-organize/data-views)
- [Customize data view fields](https://www.elastic.co/elastic/docs-builder/docs/4120/explore-analyze/find-and-organize/data-views/customize-data-view-fields)
- [Explore your data with runtime fields](https://www.elastic.co/elastic/docs-builder/docs/4120/explore-analyze/find-and-organize/data-views/runtime-fields)