| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285 | [[modules-scripting-using]]=== How to use scriptsWherever scripting is supported in the Elasticsearch API, the syntax followsthe same pattern:[source,js]-------------------------------------  "script": {    "lang":   "...",  <1>    "inline" | "stored" | "file": "...", <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 `inline`, `stored`, or `file`.<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<<search-request-script-fields, scripted field>>:[source,js]-------------------------------------PUT my_index/my_type/1{  "my_field": 5}GET my_index/_search{  "script_fields": {    "my_doubled_field": {      "script": {        "lang":   "expression",        "inline": "doc['my_field'] * multiplier",        "params": {          "multiplier": 2        }      }    }  }}-------------------------------------// CONSOLE[float]=== Script Parameters`lang`::    Specifies the language the script is written in.  Defaults to `painless` but    may be set to any of languages listed in <<modules-scripting>>. The    default language may be changed in the `elasticsearch.yml` config file by    setting `script.default_lang` to the appropriate language.`inline`, `stored`, `file`::    Specifies the source of the script.  An `inline` script is specified    `inline` as in the example above, a `stored` script is specified `stored`    and is retrieved from the cluster state (see <<modules-scripting-stored-scripts,Stored Scripts>>),    and a `file` script is retrieved from a file in the `config/scripts`    directory (see <<modules-scripting-file-scripts, File Scripts>>).+While languages like `expression` and `painless` can be used out of the box asinline or stored scripts, other languages can only bespecified as `file` unless you first adjust the default<<modules-scripting-security,scripting security settings>>.`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 thecompiled version in a cache. Compilation can be a heavy process.If you need to pass variables into the script, you should pass them in asnamed `params` instead of hard-coding values into the script itself.  Forexample, if you want to be able to multiply a field value by differentmultipliers, don't hard-code the multiplier into the script:[source,js]----------------------  "inline": "doc['my_field'] * 2"----------------------// NOTCONSOLEInstead, pass it in as a named parameter:[source,js]----------------------  "inline": "doc['my_field'] * multiplier",  "params": {    "multiplier": 2  }----------------------// NOTCONSOLEThe first version has to be recompiled every time the multiplier changes.  Thesecond 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 perminute will be compiled. You can change this setting dynamically by setting`script.max_compilations_per_minute`.========================================[float][[modules-scripting-file-scripts]]=== File-based ScriptsTo increase security, non-sandboxed languages can only be specified in scriptfiles stored on every node in the cluster.  File scripts must be saved in the`scripts` directory whose default location depends on whether you use  the<<zip-targz-layout,`zip`/`tar.gz`>> (`$ES_HOME/config/scripts/`),<<rpm-layout,RPM>>, or <<deb-layout,Debian>> package.  The default may bechanged with the `path.scripts` setting.The languages which are assumed to be safe by default are: `painless`,`expression`, and `mustache` (used for search and query templates).Any files placed in the `scripts` directory will be compiled automaticallywhen the node starts up and then <<reload-scripts,every 60 seconds thereafter>>.The file should be named as follows: `{script-name}.{lang}`.  For instance,the following example creates a Groovy script called `calculate-score`:[source,sh]--------------------------------------------------cat "Math.log(_score * 2) + params.my_modifier" > config/scripts/calculate_score.painless--------------------------------------------------This script can be used as follows:[source,js]--------------------------------------------------GET my_index/_search{  "query": {    "script": {      "script": {        "lang":   "painless", <1>        "file":   "calculate_score", <2>        "params": {          "my_modifier": 2        }      }    }  }}--------------------------------------------------// CONSOLE// TEST[continued]<1> The language of the script, which should correspond with the script file suffix.<2> The name of the script, which should be the name of the file.The `script` directory may contain sub-directories, in which case thehierarchy of directories is flattened and concatenated with underscores.  Ascript in `group1/group2/my_script.painless` should use `group1_group2_myscript`as the `file` name.[[reload-scripts]][float]==== Automatic script reloadingThe `scripts` directory will be rescanned every `60s` (configurable with the`resource.reload.interval` setting) and new, changed, or removed scripts willbe compiled, updated, or deleted from the script cache.Script reloading can be completely disabled by setting`script.auto_reload_enabled` to `false`.[float][[modules-scripting-stored-scripts]]=== Stored ScriptsScripts may be stored in and retrieved from the cluster state using the`_scripts` end-point.==== Deprecated NamespaceThe namespace for stored scripts using both `lang` and `id` as a uniqueidentifier has been deprecated.  The new namespace for stored scripts willonly use `id`. Stored scripts with the same `id`, but different `lang`'swill no longer be allowed in 6.0.  To comply with the new namespace forstored scripts, existing stored scripts should be deleted and put again.Any scripts that share an `id` but have different `lang`s will need tobe re-named.  For example, take the following:"id": "example", "lang": "painless""id": "example", "lang": "expressions"The above scripts will conflict under the new namespace since the id's arethe same.  At least one will have to be re-named to comply with the newnamespace of only `id`.As a final caveat, stored search templates and stored scripts sharethe same namespace, so if a search template has the same `id` as astored script, one of the two will have to be re-named as well usingdelete and put requests.==== Request ExamplesThe 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",    "code": "Math.log(_score * 2) + params.my_modifier"  }}-----------------------------------// CONSOLEThis same script can be retrieved with:[source,js]-----------------------------------GET _scripts/calculate-score-----------------------------------// CONSOLE// TEST[continued]Stored scripts can be used by specifying the `stored` parameters as follows:[source,js]--------------------------------------------------GET _search{  "query": {    "script": {      "script": {        "stored": "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 CachingAll scripts are cached by default so that they only need to be recompiledwhen updates occur. File scripts keep a static cache and will always residein memory. Both inline and stored scripts are stored in a cache that can evictresiding scripts. By default, scripts do not have a time-based expiration, butyou 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 stored scripts is limited to 65,535 bytes. This can bechanged by setting `script.max_size_in_bytes` setting to increase that softlimit, but if scripts are really large then alternatives like<<modules-scripting-native,native>> scripts should be considered instead.
 |