- 写在前面
- painless是一个较新的脚本语言,毕竟不是一加一等于二那么简单,开始不懂是很正常的,如果看不懂 请看第二遍第三遍乃至N次 相信我 一定能看得懂的,书读百遍,其义自见
es5以上版本推出了简单安全快捷的painless脚本来替代原有的一些脚本语言,最近正好需要过滤查询一些逻辑相对复杂的数据并对原有的groovy脚本进行升级,所以对painless进行了学习,发现网上对这个脚本的说明非常少, 官网有英文版的说明,所以特将学习结果分享出来。
painless安全且高效,书写方法和java类似,安全是因为painless提供了一个方法的白名单(链接:painless支持的类),即链接地址里的所有类和方法,除了这些方法以外的所有方法都不允许使用,而不是像groovy一样 提供一个较浅的沙盒很容易被利用(groovy漏洞分析),从而保证了安全性;高效是因为painless是由es团队自己开发的脚本,且不支持重载方法,从而保证了高效性(不支持重载方法,当一个def动态参数被定义立即就能获得这个参数对应的静态类,而不需要一个一个去遍历所有的重载方法,这正是比groovy高效的地方),且无需安装其他插件,即写即用,容易上手。
以下为es+painless脚本筛选数据举例及分析:
- 举个例子
首先设想一个场景:
一个球队,评选最有潜力球员,简单按进球数多少排序很好实现。但助攻和普通进攻也可以作为一个评选指标,最后需求为进球数权重5,助攻权重3,普通进攻权重2的方式为球员排名这怎么排序呢?单单靠dsl写起来很复杂。可用脚本定义好逻辑,让es去调用返回结果即可
准备一个球队的数据,配置好elasticsearch,并启动
工具:postman(这是一个可以模拟请求的url工具,且可返回结果)
在postman中按下图输入地址:127.0.0.1:8200/football/player/_bulk?refresh
选中Body-->raw-->JSON……
并在Body中键入球队的队员信息内容(球队信息内容来自网络,侵删):
{"index":{"_id":1}}
{"first":"johnny","last":"gaudreau","goals":[9,27,1],"assists":[17,46,0],"gp":[26,82,1],"born":"1993/08/13"}{"index":{"_id":2}}
{"first":"sean","la