如何使用脚本
无论Elasticsearch API支持何种脚本,语法都遵循相同的模式:
"script": {
"lang": "...",
"source" | "id": "...",
"params": { ... }
}
- 脚本编写的语言,默认为
painless
。 - 脚本本身可以指定为内联脚本的
source
或存储脚本的id
。 - 应传递给脚本的任何命名参数。
例如,在搜索请求中使用以下脚本来返回脚本字段:
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
}
}
}
}
}
脚本参数
lang
- 指定编写脚本的语言,默认为
painless
。
source
,id
- 指定脚本的来源,
inline
脚本是指定source
,如上例所示,存储的脚本是指定的id
,并从群集状态中检索(请参阅存储的脚本)。
params
- 指定作为变量传递到脚本的任何命名参数。
首选参数
Elasticsearch第一次看到一个新脚本,它会编译它并将编译后的版本存储在缓存中,编译可能是一个繁重的过程。
如果需要将变量传递给脚本,则应将它们作为命名参数传递给脚本本身而不是硬编码值,例如,如果你希望能够将字段值乘以不同的乘数,请不要将乘数硬编码到脚本中:
"source": "doc['my_field'] * 2"
相反,将其作为命名参数传递:
"source": "doc['my_field'] * multiplier",
"params": {
"multiplier": 2
}
第一个版本每次乘数改变时都必须重新编译,第二个版本只编译一次。
如果你在很短的时间内编译了太多独特的脚本,Elasticsearch将使用circuit_breaking_exception
错误拒绝新的动态脚本。默认情况下,每分钟将编译最多15个内联脚本,你可以通过设置script.max_compilations_rate
动态更改此设置。
简短脚本形式
可以使用简短脚本形式来简化,在简短形式中,script
由字符串而不是对象表示,该字符串包含脚本的源。
简写:
"script": "ctx._source.likes++"
正常形式的相同脚本:
"script": {
"source": "ctx._source.likes++"
}
存储的脚本
可以使用_scripts
端点将脚本存储在集群状态中并从集群状态中检索脚本。
请求示例
以下是使用位于/_scripts/{id}
的存储脚本的示例。
首先,在集群状态下创建名为calculate-score
的脚本:
POST _scripts/calculate-score
{
"script": {
"lang": "painless",
"source": "Math.log(_score * 2) + params.my_modifier"
}
}
可以使用以下命令检索相同的脚本:
GET _scripts/calculate-score
可以通过指定id
参数来使用存储的脚本,如下所示:
GET _search
{
"query": {
"script": {
"script": {
"id": "calculate-score",
"params": {
"my_modifier": 2
}
}
}
}
}
删除:
DELETE _scripts/calculate-score
脚本缓存
默认情况下,所有脚本都被缓存,因此只有在更新发生时才需要重新编译它们,默认情况下,脚本没有基于时间的过期,但你可以使用script.cache.expire
设置更改此行为,你可以使用script.cache.max_size
设置配置此缓存的大小,默认情况下,缓存大小为100
。
存储脚本的大小限制为65,535字节,这可以通过设置script.max_size_in_bytes
设置来增加软限制来更改,但如果脚本非常大,则应考虑原生脚本引擎。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。