elasticsearch painless最强教程

何为painlesspainless的特性简单的例子具体例子初始化数据用painless获取doc的值通过painless更新对象值单条记录更新批量更新Dates

大家好,又见面了,我是你们的朋友全栈君。

记得以前写过一个postman的最强教程,只可惜因为工作的原因,没再继续做测试,最终也没有写完。有点丧。。。这段时间在研究实时日志分析系统ELK,发现围绕ES这个搜索引擎或者说document数据库而开发的各种工具和周边居然是令人震惊的完善。ES真的不单单是一个分词,搜索的引擎,在各种功能和应用场景的完备性上已经不输很多数据库产品,比如mongoDB。本文着重介绍的ES 5.0版本后推出painless。(不过看来是个冷门,没人用啊)

何为painless

ElasticStack在升级到5.0版本之后,带来了一个新的脚本语言,painless。这里说“新的“是相对与已经存在groove而言的。还记得Groove脚本的漏洞吧,Groove脚本开启之后,如果被人误用可能带来各种漏洞,为什么呢,主要是这些外部的脚本引擎太过于强大,什么都能做,用不好或者设置不当就会引起安全风险,基于安全和性能方面,所以elastic.co开发了一个新的脚本引擎,名字就叫Painless,顾名思义,简单安全,无痛使用,和Groove的沙盒机制不一样,Painless使用白名单来限制函数与字段的访问,针对es的场景来进行优化,只做es数据的操作,更加轻量级,速度要快好几倍,并且支持Java静态类型,语法保持Groove类似,还支持Java的lambda表达式。

painless的特性

painless可以用在所有可以使用script的场景下,并具有以下特性:

  • 高性能。painless在es的运行速度是其他语言的数倍。这里写图片描述
  • 安全。使用白名单来限制函数与字段的访问,避免了可能的安全隐患
  • 可选类型。你可以在脚本当中使用强类型的编程方式或者动态类型的编程方式。
  • 语法。扩展了java的基本语法以兼容groove风格的脚本语言特性,使得plainless易读易写
  • 有针对的优化。这门语言是为elasticsearch专门定制的。

简单的例子

要了解这门东西,肯定要先看看它能做到什么才能激发起兴趣。先简单看一下例子,和各种groove,python,js们,没有什么区别,但要特别注意,使用强类型编程方式可以极大的加快运行速率

#动态类型的写法
def first = input.doc.first_name.0;

def last  = input.doc.last_name.0;
 return first + " " + last;

#强类型(10倍速度于上面的动态类型)
String first = (String)((List)((Map)input.get("doc")).get("first_name")).get(0);

String last  = (String)((List)((Map)input.get("doc")).get("last_name")).get(0);
 return first + " " + last;

具体例子

初始化数据

我们先输入一串曲棍球的数据到ES当中。

PUT hockey/player/_bulk?refresh
{"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","last":"monohan","goals":[7,54,26],"assists":[11,26,13],"gp":[26,82,82],"born":"1994/10/12"}
{"index":{"_id":3}}
{"first":"jiri","last":"hudler","goals":[5,34,36],"assists":[11,62,42],"gp":[24,80,79],"born":"1984/01/04"}
{"index":{"_id":4}}
{"first":"micheal","last":"frolik","goals":[4,6,15],"assists":[8,23,15],"gp":[26,82,82],"born":"1988/02/17"}
{"index":{"_id":5}}
{"first":"sam","last":"bennett","goals":[5,0,0],"assists":[8,1,0],"gp":[26,1,0],"born":"1996/06/20"}
{"index":{"_id":6}}
{"first":"dennis","last":"wideman","goals":[0,26,15],"assists":[11,30,24],"gp":[26,81,82],"born":"1983/03/20"}
{"index":{"_id":7}}
{"first":"david","last":"jones","goals":[7,19,5],"assists":[3,17,4],"gp":[26,45,34],"born":"1984/08/10"}
{"index":{"_id":8}}
{"first":"tj","last":"brodie","goals":[2,14,7],"assists":[8,42,30],"gp":[26,82,82],"born":"1990/06/07"}
{"index":{"_id":39}}
{"first":"mark","last":"giordano","goals":[6,30,15],"assists":[3,30,24],"gp":[26,60,63],"born":"1983/10/03"}
{"index":{"_id":10}}
{"first":"mikael","last":"backlund","goals":[3,15,13],"assists":[6,24,18],"gp":[26,82,82],"born":"1989/03/17"}
{"index":{"_id":11}}
{"first":"joe","last":"colborne","goals":[3,18,13],"assists":[6,20,24],"gp":[26,67,82],"born":"1990/01/30"}

这里极其建议在练习的时候使用kibana上的Dev Tools,这个东西有多好用谁用谁知道,它可以自动补齐es的各种query语法,牛不牛?而且就像markdown一样,做到左右分屏,所见即所得。

这里写图片描述

用painless获取doc的值

下面的例子中,我们通过function_score::script_score更新每个document的score。其中用到了for循环,和强类型定义int
可以看到运行之后,_score的值,编程了goals值的sum。
这里写图片描述

以下是更多的取值的例子:

GET hockey/_search
{
  "query": {
    "match_all": {}
  },
  "script_fields": {
    "total_goals": {
      "script": {
        "lang": "painless",
        "inline": "int total = 0; for (int i = 0; i < doc['goals'].length; ++i) { total += doc['goals'][i]; } return total;" } } } }
GET hockey/_search
{
  "query": {
    "match_all": {}
  },
  "sort": {
    "_script": {
      "type": "string",
      "order": "asc",
      "script": {
        "lang": "painless",
        "inline": "doc['first.keyword'].value + ' ' + doc['last.keyword'].value" } } } }

这里需要注意几点:

  • 这里都是_search操作,多个操作之间会形成管道,既query::match_all的输出会作为script_fields或者sort的输入。
  • _search操作中所有的返回值,都可以通过一个map类型变量doc获取。和所有其他脚本语言一样,用[]获取map中的值。这里要强调的是,doc只可以在_search中访问到。在下一节的例子中,你将看到,使用的是ctx
  • _search操作是不会改变document的值的,即便是script_fields,你只能在当次查询是能看到script输出的值。
  • doc['first.keyword']这样的写法是因为doc[]返回有可能是分词之后的value,所以你想要某个field的完整值时,请使用keyword

通过painless更新对象值

上一节讲了如何读取值,在读取值的时候,query的response虽然能够读到一个新值,但这个值并没有写入document当中。要更新值,需要通过_updateAPI。

单条记录更新

如下图,通过_updateAPI的script,我们可以增加一个新的field:nick:
这里写图片描述
可以更改一个值:
这里写图片描述

这里需要注意的是:我们不再使用doc来访问对象,而是用ctx。

批量更新

在大多数应用场景下,我们是很少用到_updateAPI的。(当然,这里不包括你用python, java等语言用for循环多条更新)。在批量更新的场景,我推荐的是_update_by_queryAPI。

这里写图片描述

这里需要注意的是:

  • 虽然_update_by_queryAPI在批量更新时,和我们第一个例子很像,先query,再update,通过管道修改全部的值。但这里仍然只能用ctx,而不是doc。如果用doc,会抛出nullpointerException。
  • 另外,在例子中,我用的是match_all query,但实际上你可以用各种query,来划定精确的query范围,只修改你想修改的值。

Dates

Date类型的field会被解析成ReadableDateTime。所以它可以支持 getYear, getDayOfWeek等方法。 例如,要取milliseconds,就屌用getMillis方法。下面的例子,取每个球员是哪年出生的:
这里写图片描述

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/125334.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • VLC 外挂字幕乱码

    VLC 外挂字幕乱码title:VLC外挂字幕乱码date:2020-01-2221:11:13tags:技术笔记最近下载了一些电影,使用VLC播放器添加了外挂字幕。问题描述:VLC添加外挂字幕乱码软件环境描述说明下载地址VLC版本3.0.8VLC3.0.8字母格式ASS/SRT字幕库解决方案启动VLC播放器;依次点击左上标题栏…

  • int32_t是什么数据类型_int32_t什么意思

    int32_t是什么数据类型_int32_t什么意思个人理解*_t中的t可以理解为typedefine。由于各个平台中对基本数据的大小定义不一样,为了兼容各个平台,C语言利用预编译和typedef可以让你最有效的维护你的代码。其实这些都不是新的数据类型,为了用户的方便,C99标准的C语言硬件为我们定义了这些类型,我们放心使用。如:int32_t其实就是32位int类型数据。附:C99标准中inttypes.h的内容000010001700…

  • android 获取收到短信验证码,Android自动获取短信验证码

    android 获取收到短信验证码,Android自动获取短信验证码如此当有短信收到时就可以将短信内容写到SD卡中的文件里在另一个java类中写个读取文件内容的方法,并在写测试用例过程中,将得到的String按验证码的具体位置截取即可。publicStringread(Stringstr)throwsIOException{Filefile=newFile(str);FileInputStreamfis=newFileInputStream(fi…

  • scikit-learn : LARS[通俗易懂]

    scikit-learn : LARS[通俗易懂]LARS正则化斯坦福大学的BradleyEfron,TrevorHastie,IainJohnstone和RobertTibshirani发现了LARS(LeastAngleRegression,最小角回归)它借用了威廉·吉尔伯特·斯特朗(WilliamGilbertStrang)介绍过的高斯消元法(Gaussianelimination)的灵感。背景LARS是一种回归手段,适

  • mac 安装pymssql

    mac 安装pymssql我们在mac环境下想连接mssqlserver数据库,首先要考虑的就是使用pymssql库,而pymssql是在freedts的基础上研发的,所以要先安装freedts,但是安装这个库之前还需有有一系列的支撑库brewinstallunixodbcpipinstallCythonpipinstallsetuptools_git我们正常直接使用pipinstallpymssql时会报下面的错误Jason-MacBook-Pro:~wangying$pipinstal..

  • CEGUI编译

    CEGUI编译CEGUI版本0.8.2依赖库使用cegui-deps-0.8.x-src由于我是要在Ogre中使用CEGUI做界面,所以渲染引擎使用Ogre,编译的Ogre版本1.9CEGUI和cegui-deps-0.8.x-src都能通过cmake创建vs项目先编译cegui-deps-0.8.x-src,使用cmake生成vs解决方案,因为不依赖别的库,所以不需要怎么配置,直接co

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号