Elasticsearch Scripting 教程
Elasticsearch中最强大、有用的功能可能是其 Scripting 功能。通过脚本功能可以执行多种操作,如获取搜索请求的特定字段,修改、删除字段。本文学习如果通过脚本功能实现这些基本功能。
1. Elasticsearch Scripting介绍
Elasticsearch使用Painless或Java创建自定义表达式脚本。在5.x版本之后Painless作为默认版本。Painless更快、安全,比其他脚本语言更简单,语法与Java、groovy类似。
script作为请求主体的一个字段,其规范包括三个部分:
# the "script" field encompasses the main body of the JSON scripting request
"script": {
# scripting language name
"lang": "painless",
# source object (or document ID) as well as the operations performed by the script
"source": "ctx._source = params.someNum",
# the parameters or values for the script's operations
"params": { "someNum = 12345" }
}
- lang
指定语言,从v5.x之后默认为Painless
- source及ctx变量
使用ctx变量访问文档的source,即:ctx._source
查询时使用doc[‘field_name’].value访问字段值。
GET /courses/_search
{
"query" : {
"match_all": {}
},
"script_fields": {
"db_enrolled": {
"script": {
"source": "doc['students_enrolled'].value * params.interval",
"params": {"interval":2}
}
}
}
}
上面示例给返回文档增加db_enrolled字段,其值为students_enrolled字段值两倍。
- params
用于给脚本设定参数,脚本中引用参数:params.name ,name表示参数名称。
2. 创建索引
POST /testscript/_create/1
{
"personalDetails": {
"name": "bob",
"age": "13"
},
"marks": {
"physics": 48,
"maths": 45,
"chemistry": 44
},
"remarks": [
"hard working",
"intelligent"
]
}
查询id为1的记录:
GET /testscript/_doc/1
返回内容:
{
"_index" : "testscript",
"_type" : "_doc",
"_id" : "1",
"_version" : 1,
"_seq_no" : 1,
"_primary_term" : 1,
"found" : true,
"_source" : {
"personalDetails" : {
"name" : "bob",
"age" : "13"
},
"marks" : {
"physics" : 48,
"maths" : 45,
"chemistry" : 44
},
"remarks" : [
"hard working",
"intelligent"
]
}
}
3. 脚本更新文档
下面示例展示使用脚本更新文档的常用操作,主要包括:
- 给索引增加新的字段
- 更新已存在数组元素值
- 删除数组元素
- 删除字段
3.1. 给已存在字段增加新的属性
上面示例中包括三门课程成绩,现在我们增加英语的分数:
POST /testscript/_update/1
{
"script": "ctx._source.marks.english=41"
}
更新后记录已经改变,并且_version版本为2:
{
"_index" : "testscript",
"_type" : "_doc",
"_id" : "1",
"_version" : 2,
"_seq_no" : 1,
"_primary_term" : 1,
"found" : true,
"_source" : {
"personalDetails" : {
"name" : "bob",
"age" : "13"
},
"marks" : {
"physics" : 48,
"maths" : 45,
"chemistry" : 44,
"english" : 41
},
"remarks" : [
"hard working",
"intelligent"
]
}
}
版本数表明文档的改变次数。
3.2. 更新已存在字段属性值
接着我们更新physics的成绩为49:
POST /testscript/_update/1
{
"script":{
"source": "ctx._source.marks.physics=params.physics",
"params": {"physics":49}
}
}
验证结果:
{
"_index" : "testscript",
"_type" : "_doc",
"_id" : "1",
"_version" : 3,
"_seq_no" : 2,
"_primary_term" : 1,
"found" : true,
"_source" : {
"personalDetails" : {
"name" : "bob",
"age" : "13"
},
"marks" : {
"physics" : 49,
"maths" : 45,
"chemistry" : 44,
"english" : 41
},
"remarks" : [
"hard working",
"intelligent"
]
}
}
physics的值为49,版本为3,和预期一致。
3.3. 删除字段属性
删除物理成绩:
POST /testscript/_update/1
{
"script":{
"source": "ctx._source.marks.remove('physics')"
}
}
验证结果:
{
"_index" : "testscript",
"_type" : "_doc",
"_id" : "1",
"_version" : 4,
"_seq_no" : 3,
"_primary_term" : 1,
"found" : true,
"_source" : {
"personalDetails" : {
"name" : "bob",
"age" : "13"
},
"marks" : {
"maths" : 45,
"chemistry" : 44,
"english" : 41
},
"remarks" : [
"hard working",
"intelligent"
]
}
}
已经没有了物理成绩,版本为4。
3.4. 删除整个字段
删除marks整个字段:
POST /testscript/_update/1
{
"script":{
"source": "ctx._source.remove('marks')"
}
}
验证结果是否一致:
{
"_index" : "testscript",
"_type" : "_doc",
"_id" : "1",
"_version" : 5,
"_seq_no" : 4,
"_primary_term" : 1,
"found" : true,
"_source" : {
"personalDetails" : {
"name" : "bob",
"age" : "13"
},
"remarks" : [
"hard working",
"intelligent"
]
}
}
3.5. 增加数组元素
增加一条评论:
POST /testscript/_update/1
{
"script":{
"source": "ctx._source.remarks.add('Love of learning')"
}
}
验证结果:
{
"_index" : "testscript",
"_type" : "_doc",
"_id" : "1",
"_version" : 6,
"_seq_no" : 5,
"_primary_term" : 1,
"found" : true,
"_source" : {
"personalDetails" : {
"name" : "bob",
"age" : "13"
},
"remarks" : [
"hard working",
"intelligent",
"Love of learning"
]
}
}
3.6. 删除数组元素
POST /testscript/_update/1
{
"script":{
"lang": "painless",
"source": "ctx._source.remarks.remove(ctx._source.remarks.indexOf('Love of learning'))"
}
}
4. 总结
本文学习了使用Elasticsearch中脚本模块简易修改文档字段值。
本文参考链接:https://blog.csdn.net/neweastsun/article/details/104287239