[[modules-scripting-using]] === How to use scripts Wherever scripting is supported in the Elasticsearch API, the syntax follows the same pattern: [source,js] ------------------------------------- "script": { "lang": "...", <1> "source" | "id": "...", <2> "params": { ... } <3> } ------------------------------------- // NOTCONSOLE <1> The language the script is written in, which defaults to `painless`. <2> The script itself which may be specified as `source` for an inline script or `id` for a stored script. <3> Any named parameters that should be passed into the script. For example, the following script is used in a search request to return a <>: [source,js] ------------------------------------- PUT my_index/_doc/1 { "my_field": 5 } GET my_index/_search { "script_fields": { "my_doubled_field": { "script": { "lang": "expression", "source": "doc['my_field'] * multiplier", "params": { "multiplier": 2 } } } } } ------------------------------------- // CONSOLE [float] === Script Parameters `lang`:: Specifies the language the script is written in. Defaults to `painless`. `source`, `id`:: Specifies the source of the script. An `inline` script is specified `source` as in the example above. A `stored` script is specified `id` and is retrieved from the cluster state (see <>). `params`:: Specifies any named parameters that are passed into the script as variables. [IMPORTANT] [[prefer-params]] .Prefer parameters ======================================== The first time Elasticsearch sees a new script, it compiles it and stores the compiled version in a cache. Compilation can be a heavy process. If you need to pass variables into the script, you should pass them in as named `params` instead of hard-coding values into the script itself. For example, if you want to be able to multiply a field value by different multipliers, don't hard-code the multiplier into the script: [source,js] ---------------------- "source": "doc['my_field'] * 2" ---------------------- // NOTCONSOLE Instead, pass it in as a named parameter: [source,js] ---------------------- "source": "doc['my_field'] * multiplier", "params": { "multiplier": 2 } ---------------------- // NOTCONSOLE The first version has to be recompiled every time the multiplier changes. The second version is only compiled once. If you compile too many unique scripts within a small amount of time, Elasticsearch will reject the new dynamic scripts with a `circuit_breaking_exception` error. By default, up to 15 inline scripts per minute will be compiled. You can change this setting dynamically by setting `script.max_compilations_rate`. ======================================== [float] [[modules-scripting-short-script-form]] === Short Script Form A short script form can be used for brevity. In the short form, `script` is represented by a string instead of an object. This string contains the source of the script. Short form: [source,js] ---------------------- "script": "ctx._source.likes++" ---------------------- // NOTCONSOLE The same script in the normal form: [source,js] ---------------------- "script": { "source": "ctx._source.likes++" } ---------------------- // NOTCONSOLE [float] [[modules-scripting-stored-scripts]] === Stored Scripts Scripts may be stored in and retrieved from the cluster state using the `_scripts` end-point. ==== Request Examples The following are examples of using a stored script that lives at `/_scripts/{id}`. First, create the script called `calculate-score` in the cluster state: [source,js] ----------------------------------- POST _scripts/calculate-score { "script": { "lang": "painless", "source": "Math.log(_score * 2) + params.my_modifier" } } ----------------------------------- // CONSOLE This same script can be retrieved with: [source,js] ----------------------------------- GET _scripts/calculate-score ----------------------------------- // CONSOLE // TEST[continued] Stored scripts can be used by specifying the `id` parameters as follows: [source,js] -------------------------------------------------- GET _search { "query": { "script": { "script": { "id": "calculate-score", "params": { "my_modifier": 2 } } } } } -------------------------------------------------- // CONSOLE // TEST[continued] And deleted with: [source,js] ----------------------------------- DELETE _scripts/calculate-score ----------------------------------- // CONSOLE // TEST[continued] [float] [[modules-scripting-using-caching]] === Script Caching All scripts are cached by default so that they only need to be recompiled when updates occur. By default, scripts do not have a time-based expiration, but you can change this behavior by using the `script.cache.expire` setting. You can configure the size of this cache by using the `script.cache.max_size` setting. By default, the cache size is `100`. NOTE: The size of scripts is limited to 65,535 bytes. This can be changed by setting `script.max_size_in_bytes` setting to increase that soft limit, but if scripts are really large then a <> should be considered.