脚本语言
- painless
ES 的脚本语言可以通过 lang 来设置,如果不设置,默认为 Painless。Painless 专为 Elasticsearch 构建,可用于脚本 API 中的任何目的,并提供最大的灵活性。而且 Painless 是 ES 内置的,无需安装其他插件来支持,而且Painless 使用 Java 语法的子集, Painless 实现了任何具有基本编码经验的人都自然熟悉的语法。 - expressions
Lucene 的表达式语言将javascript表达式编译为字节码。
脚本使用格式
"script": {
"lang": "...",
"source" | "id": "...",
"params": { ... }
}
- lang
指定编写脚本所用的语言。默认为 painless。 - source 或 id 脚本本身
- source 内联脚本(就是脚本代码)
- 存储脚本 id 。使用存储的脚本 API 创建和管理存储的脚本。(脚本代码存储在别处,此处用id引用)
- params
指定作为变量传递到脚本中的任何命名参数。使用参数而不是硬编码值来减少编译时间。
脚本中访问文档字段
在脚本中访问文档字段一般有如下两种方式:
- doc 访问,列如:doc[‘age’].value
- fieldAPI 访问
- field(‘my_field’).get(<default_value>):例如:field(‘age’).get(-1)
- $(‘my_field’,‘default_value’)
script_fields 对查询字段进行计算
{
"_source":{
"excludes":["remark"]
},
"query": {
"script": {
"script": {
"source": "doc['age'].value > 20 && $('sex',-1) == 0",
"lang": "painless"
}
}
},
"script_fields": {
"tt":{
"script": {
"source": "$('height',0) + 1"
}
}
}
}
示例结果 tt 字段为我们使用脚本对 height 字段进行了 +1 操作后的结果。
结果
{
"took": 12,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 374,
"relation": "eq"
},
"max_score": 1.0,
"hits": [
{
"_index": "person",
"_id": "265",
"_score": 1.0,
"_source": {
"id": 266,
"name": "文敏",
"age": 31,
"height": 1.75,
"birthday": "1987-05-07 11:47:16",
"sex": 0
},
"fields": {
"tt": [
2.75
]
}
},
{
"_index": "person",
"_id": "267",
"_score": 1.0,
"_source": {
"id": 268,
"name": "董超",
"age": 42,
"height": 1.67,
"birthday": "1974-09-04 12:27:55",
"sex": 0
},
"fields": {
"tt": [
2.67
]
}
},
{
"_index": "person",
"_id": "269",
"_score": 1.0,
"_source": {
"id": 270,
"name": "江娟",
"age": 46,
"height": 1.04,
"birthday": "1975-12-05 02:03:17",
"sex": 0
},
"fields": {
"tt": [
2.04
]
}
},
{
"_index": "person",
"_id": "277",
"_score": 1.0,
"_source": {
"id": 278,
"name": "卢杰",
"age": 28,
"height": 1.73,
"birthday": "2012-01-31 01:28:44",
"sex": 0
},
"fields": {
"tt": [
2.73
]
}
},
{
"_index": "person",
"_id": "279",
"_score": 1.0,
"_source": {
"id": 280,
"name": "黎霞",
"age": 24,
"height": 1.61,
"birthday": "2003-09-08 10:44:28",
"sex": 0
},
"fields": {
"tt": [
2.6100001
]
}
},
{
"_index": "person",
"_id": "281",
"_score": 1.0,
"_source": {
"id": 282,
"name": "武芳",
"age": 42,
"height": 1.34,
"birthday": "1994-11-11 13:48:35",
"sex": 0
},
"fields": {
"tt": [
2.3400002
]
}
},
{
"_index": "person",
"_id": "283",
"_score": 1.0,
"_source": {
"id": 284,
"name": "白杰",
"age": 28,
"height": 1.47,
"birthday": "2020-07-04 15:59:12",
"sex": 0
},
"fields": {
"tt": [
2.47
]
}
},
{
"_index": "person",
"_id": "285",
"_score": 1.0,
"_source": {
"id": 286,
"name": "高秀英",
"age": 31,
"height": 1.61,
"birthday": "1989-12-23 18:01:15",
"sex": 0
},
"fields": {
"tt": [
2.6100001
]
}
},
{
"_index": "person",
"_id": "289",
"_score": 1.0,
"_source": {
"id": 290,
"name": "江丽",
"age": 21,
"height": 1.55,
"birthday": "1979-03-23 15:42:32",
"sex": 0
},
"fields": {
"tt": [
2.55
]
}
},
{
"_index": "person",
"_id": "291",
"_score": 1.0,
"_source": {
"id": 292,
"name": "杜霞",
"age": 40,
"height": 1.26,
"birthday": "1995-02-19 04:09:23",
"sex": 0
},
"fields": {
"tt": [
2.26
]
}
}
]
}
}
脚本中使用参数
ES 在第一次执行脚本时,会编译脚本并将编译后的版本存储在缓存。是否将可变内容参数化,这个和sql 中 Statement 和 PrepareStatement 的差别是一样的。
{
"_source":{
"excludes":["remark"]
},
"query": {
"script": {
"script": {
"source": "$('age',0) > params.age",
"params":{
"age" : 30
}
}
}
}
}
存储脚本
创建或更新存储脚本
PUT _scripts/<script-id>
POST _scripts/<script-id>
路径参数
<script-id>
(必需,字符串)存储的脚本或搜索模板的标识符。在集群内必须是唯一的。
正文参数
- lang
(必需,字符串) 脚本语言。 - source
(必需,字符串或对象)对于脚本,包含脚本的字符串。 - params
(可选,对象)脚本的参数。
PUT /_scripts/test1
{
"script": {
"lang": "painless",
"source": "$('age',0) > params['age']"
}
}
参数 age 我们在此没有直接定义,在脚本执行时直接配置即可
在查询中使用
{
"_source":{
"excludes":["remark"]
},
"query": {
"script": {
"script": {
"id": "test1",
"params":{
"age" : 40
}
}
}
}
}
删除存储脚本
DELETE /_scripts/test1