Elasticsearch中脚本(script)的使用

Elasticsearch中脚本的使用

​ Elasticsearch支持多种脚本语言。在 ES 中,脚本语言主要是 Painless,这是 Elasticsearch 自家开发的一种安全、高效并且易于学习的语言。除了 Painless,Elasticsearch 也支持其他几种脚本语言,如 Lucene 的表达式语言,但 Painless 是推荐和默认的选项。

以下是一些常见的使用脚本的场景:

  1. 计算字段:你可以使用脚本在查询时动态地改变或添加字段的值。
  2. 脚本查询:在查询中使用脚本进行复杂的条件判断。
  3. 脚本聚合:使用脚本进行更复杂的聚合计算。

使用脚本时需要注意的是,由于涉及到运行时的计算,过度或者不恰当的使用脚本可能会对性能造成影响。另外,由于脚本具有执行任意代码的能力,因此需要确保脚本的使用在一个安全的环境中,并且只运行信任的脚本。

1、script格式

语法都遵循相同的模式

json 复制代码
"script": {
    "lang":   "...",  
    "source" | "id": "...", 
    "params": { ... } 
  }
  • lang:指定编程语言,默认是painless,还有其他编程语言选项如expression
  • source | id: source,id二者选其一,source后面接inline脚本(就是将脚本逻辑直接放在DSL里面 ),id对应一个stored脚本(就是预先设置类似UDF,使用的时候根据UDF的id进行调用和传参
  • params:在脚本中任何有名字的参数,用params传参

2、访问文档字段和特殊变量

根据脚本的使用位置,它将有权访问某些特殊变量和文档字段。

更新 (update)中使用的脚本, 查询更新 (update_by_query),或重新索引 (reindex)API将有权访问ctx变量,该变量公开

  • ctx._source ====> 访问文档_source字段。
  • ctx.op ====> 应应用于文档的操作:indexdelete
  • ctx._index等 ===> 访问文档元数据字段,其中一些可能是只读的。

使用script脚本修改某文档的某个字段,先插入一条文档

3、示例

使用script修改一个字段:

json 复制代码
//新增一条数据
PUT my-index-000001/_doc/3?refresh
{
  "first_name": "Barry",
  "last_name": "寒"
}

//script修改一个字段
POST my-index-000001/_update/3
{
  "script": {
    "source": "ctx._source.first_name= '傲'"
  }
}

//或者
POST my-index-000001/_update/3
{
  "script": {
    "source": "ctx._source['first_name']= '不吃肥肉'"
  }
}

script脚本更新字段、除了直接使用=赋值修改的情况,还可以对字段使用函数处理数值运算,比如加减乘除开方等等

json 复制代码
//将所有 '信息信息' 字符替换为 '信息'
POST my-index-000001/_update_by_query
{
  "script": {
    "source": "ctx._source.first_name = ctx._source.first_name.replace('信息信息','信息')"
  },
  "query": {
    "match_all": {}
  }
}
json 复制代码
//新增一条数据
PUT my-index-000001/_doc/4?refresh
{
  "first_name": "傲",
  "last_name": "寒",
  "tags":["java"]
}

//使用函数 新增一个tags 'pgsql'
POST my-index-000001/_update/4
{
  "script": {
    "source": "ctx._source.tags.add('pgsql')"
  }
}


// ctx.op文档操作 删除 id为4的数据
POST my-index-000001/_update/4
{
  "script": {
    "lang": "painless",
    "source": "ctx.op='delete'"
  }
}

script中的查询

json 复制代码
GET /my-index-000001/_search
{
  "script_fields": {
    "full_name": {
      "script": {
        "source": "params._source.first_name + '' + params._source.last_name"
      }
    }
  }
}

script在聚合中使用

json 复制代码
GET /my-index-000001/_search
{
 "query": {
   "match_all": {}
 },
 "aggs": {
   "full_name": {
     "terms": {
       "script": {
         "source": "params._source.first_name + '' + params._source.last_name"
       }
     }
   }
 }
}
相关推荐
爱勇宝26 分钟前
我做了一个排版器,也踩了一遍富文本复制的坑
前端·后端·微信
布朗克16831 分钟前
Go 入门到精通-33-unsafe 与 CGO
开发语言·后端·golang·unsafe·cgo
铁皮饭盒38 分钟前
面试官:如何用 Bun + JS 实现安全的文件 MCP 工具集
前端·javascript·后端
小Ti客栈1 小时前
Spring Boot 整合 Swagger2 和 Knife4j实现接口文档与可视化调试
java·spring boot·后端
明月_清风1 小时前
💰 DeFi 入门完全指南:从 Uniswap 到 Aave,一文读懂去中心化金融
后端·web3
Conan在掘金1 小时前
鸿蒙报错速查:struct 里嵌套 @Component struct 就炸,Unexpected keyword 编译报错,根因 + 真解法
后端
妙码生花1 小时前
从 PHP 到 AI + Golang,程序员自救转型手记(三十六):多驱动上传接口
后端·go·ai编程
明月_清风1 小时前
🎨 NFT 全景解析:从 JPEG 到数字所有权革命
后端·web3
李明卫杭州1 小时前
mise 管理工具详解
前端·后端
颜进强1 小时前
从零搭建私人 RAG 实战:让 Claude Code 按需查询知识库
前端·后端·ai编程