脚本

脚本 #

Easysearch 提供了内置的脚本语言,可以在查询、聚合、摄入管道、更新操作等多种场景中使用脚本来实现自定义逻辑。

支持的脚本语言 #

语言用途沙盒安全性能
Painless通用脚本语言,推荐默认使用✅ 是高(编译为字节码)
Mustache搜索模板(参数化查询)✅ 是
Expressions高性能数学表达式(排序和评分)✅ 是极高(编译为字节码)

脚本使用方式 #

Easysearch 中使用脚本有三种方式:

1. 内联脚本(Inline) #

直接在请求体中编写脚本代码,适合临时性操作:

GET my_index/_search
{
  "script_fields": {
    "total_price": {
      "script": {
        "lang": "painless",
        "source": "doc['price'].value * doc['quantity'].value"
      }
    }
  }
}

2. 存储脚本(Stored Scripts) #

将常用脚本预先存储在集群中,通过 ID 引用,适合反复使用的脚本。详见 存储脚本

POST _scripts/calculate_total
{
  "script": {
    "lang": "painless",
    "source": "doc['price'].value * params['tax_rate']"
  }
}

使用时通过 ID 引用:

GET my_index/_search
{
  "script_fields": {
    "total": {
      "script": {
        "id": "calculate_total",
        "params": {
          "tax_rate": 1.08
        }
      }
    }
  }
}

3. 搜索模板(Search Templates) #

使用 Mustache 语言参数化整个查询体,适合面向用户的搜索场景。详见 Search Template API

脚本结构 #

所有脚本请求都遵循相同的结构:

"script": {
  "lang": "painless",
  "source": "脚本代码",
  "params": {
    "参数名": "参数值"
  }
}
字段说明
lang脚本语言,默认为 painless,可省略
source内联脚本的代码内容
id存储脚本的 ID(与 source 二选一)
params传递给脚本的参数(推荐使用参数而非硬编码值,可利用脚本缓存)

脚本可用场景 #

场景说明示例
Script Query用脚本作为查询条件过滤文档过滤价格 > 阈值的文档
Script Score用脚本自定义评分逻辑结合时效性和热度的评分公式
Script Fields在搜索结果中返回脚本计算的字段计算折扣后价格
Update API用脚本更新文档字段增减计数器、追加数组元素
Update By Query用脚本批量更新文档批量重命名字段
Ingest Script Processor在摄入管道中用脚本处理文档格式转换、字段拆分
Scripted Metric Aggregation用脚本实现自定义聚合自定义业务指标计算
Sort Script用脚本自定义排序逻辑按地理距离和评分综合排序
Reindex Script在重建索引时用脚本转换文档字段映射转换

脚本缓存 #

Easysearch 会缓存编译后的脚本以提高性能。缓存相关设置:

设置默认值说明
script.cache.max_size3000缓存中最多保留的脚本数
script.cache.expire无过期缓存过期时间(如 10m
script.max_compilations_rate150/5m每个时间窗口允许的最大编译次数

最佳实践:始终使用 params 传递变量值,而不是将值硬编码到 source 中。这样相同结构的脚本可以共享编译缓存,大幅减少编译开销。

脚本安全 #

Painless 语言在安全沙盒中运行,只允许访问白名单内的 Java API,无法执行文件操作、网络请求或任何危险操作。可以通过以下设置控制脚本功能:

设置默认值说明
script.allowed_types全部允许的脚本类型:inlinestored
script.allowed_contexts全部允许的脚本上下文(如 scoreupdateingest

例如,仅允许内联的 Painless 脚本和存储脚本:

script.allowed_types: inline, stored