Elasticsearch 中的脚本编程能力
elasticsearch 和 关系型数据库在使用上类似,都是建表(创建mapping)、插入、查询、删除、更新、表结构变更(mapping 变更)等等。基于基本的增删改查用的最多也比较简单,而mapping结构的处理要相对复杂一点。这里简单介绍一下如何使用es 的脚本能力轻松变更mapping 结构。
为成熟的中间件提供编程能力正成为中间件热衷的能力,比如redis也支持lua编程(《在Redis中使用Lua脚本》)
〇 es 脚本能力简介
es脚本能实现一些rest api无法搞定的事情,从这一个角度看,它存在的意义重大:因为它有一个无法被代替的能力。如果我们自己身上也有别人无法代替的特质,那么我们就是这个世界重要的组成部分😁。
可惜我们没有,所以地球离了我们还是在转😭
从1.4版本开始,es推荐使用groovy做为默认脚本。实际上,es 支持好几种脚本引擎,除了groovy,还有大家熟悉的js/python,还有Expression/Mustache/mvel。大家可以自行了解一下。
通过es脚本,我们可以更新es记录的字段、增加字段、删除字段,而后面这两个能力,不使用脚本的话实现起来很费劲。
壹 更新字段
我们先来创建一个索引:
curl -XPUT 'localhost:9200/testindex/_doc/1' -H 'content-Type:application/json' -d '{
"marks": {
"physics": 48,
"maths": 45,
"chemistry": 44
},
"remarks": [
"hard working",
"intelligent"
]
}'
这条记录包含两个nested字段,并且没有指明字段类型,所以es会自动映射:
"marks": {
"properties": {
"chemistry": {
"type": "long"
},
"maths": {
"type": "long"
},
"physics": {
"type": "long"
}
}
},
"remarks": {
"type": "text",
"fields": {
"keyword": {
"ignore_above": 256,
"type": "keyword"
}
}
}
接下来通过脚本更新物理课的分数为59(差点及格):
希望你已经知道不使用脚本是如何更新记录的
curl -XPOST 'localhost:9200/testindex/_doc/1/_update' -H 'Content-Type: application/json' -d '{
"script" : "ctx._source.marks.physics = 59"
}'
我们看一下请求格式:json参数有一个字段叫script,里面通过ctx的_source拿到记录,然后通过点号指明marks字段的physics字段的值。
贰 增加字段
不使用脚本如何增加字段?这个已经不是一个常规问题,虽然做法简单,但是了解的人不多:
curl -XPUT 'http://127.0.0.1:9200/testindex/_mapping/_doc?pretty' -H 'Content-Type: application/json' -d'
{
"properties": {
"long_followerCount": {
"type": "long"
}
}
}'
通过index/_mapping/type的PUT请求直接传入一个字段就可以新增。
那通过脚本怎么实现呢?
curl -XPOST 'localhost:9200/testindex/_doc/1/_update' -H 'Content-Type: application/json' -d '{
"script" : "ctx._source.marks.english = 41"
}'
直接写入一个值就完成了新增。当然是动态结构了。
现在整个mapping是:
"properties": {
"marks": {
"properties": {
"chemistry": {
"type": "long"
},
"maths": {
"type": "long"
},
"physics": {
"type": "long"
},
"english": {
"type": "long"
}
}
},
"long_followerCount": {
"type": "long"
},
"remarks": {
"type": "text",
"fields": {
"keyword": {
"ignore_above": 256,
"type": "keyword"
}
}
}
}
叁 删除字段
通过脚本删除字段也很简单:
curl -XPOST 'localhost:9200/testindex/_doc/1/_update' -H 'Content-Type: application/json' -d '{
"script": "ctx._source.marks.remove(\"physics\")"
}'
curl -XPOST 'localhost:9200/testindex/_doc/1/_update' -H 'Content-Type: application/json' -d '{
"script": "ctx._source.remove(\"marks\")"
}'
上面分别通过记录删除了它的physics和marks字段。是不是比以前的方法简单多了?
肆 自定义查询
通过脚本可以进行自定义的字段及格式查询:
curl -XGET 'localhost:9200/testindex/_search' -H 'Content-Type: application/json' -d '{
"script_fields": {
"my_field": {
"script": {
"lang": "expression",
"source": "doc['long_followerCount'] * multiplier",
"params": {
"multiplier": 2
}
}
}
}
}'
这里查询的是long_followerCount这个字段的2倍。
