首页 > 编程知识 正文

elasticsearch入门,painless脚本

时间:2023-05-05 09:22:18 阅读:161558 作者:2476

painlesspainless特性简单的例子具体例子什么是用初始化数据painless取得doc的值用painless更新对象值的单记录更新批量更新Dates

我记得以前写过postman最强的教程,可惜为了工作没有继续测试,最终没有写完。 我有点在服丧。 请参阅。 请参阅。 前几天,我在研究实时日志分析系统ELK,发现以ES这个搜索引擎,或者document数据库为中心开发的各种工具和周边都惊人地丰富。 ES真的不仅仅是分词,还是搜索引擎,在mongoDB等多种功能和APP场景的完整性方面不输于很多数据库产品。 在本文重点介绍的ES 5.0版本之后推出painless。 (但是,好像是个冷漠的人,没人用啊)

painless ElasticStack升级到5.0版后,带来了什么新的脚本语言,painless? 这里说“新的”,是针对已经存在的groove。 还记得Groove脚本的漏洞吗? Groove脚本打开后,如果被人误用,可能会带来各种漏洞。 为什么呢,主要是这些外部的脚本引擎太强大了,什么都做得出来。 如果不能很好地使用,或者设置错误,会引起安全风险。 出于安全和性能方面的考虑,elastic.co开发了新的脚本引擎。 名字叫Painless。 无痛使用与Groove沙箱机制不同,Painless使用白名单限制函数和字段访问,根据es场景进行优化,只操作es数据,重量更轻,速度快几倍,javvs

painless特性painless可用于所有可以使用脚本的场景,并具有以下特性:

高性能。 painless在es上的运行速度是其他语言的数倍。 很安全。 通过使用白名单限制对函数和字段的访问,避免可能的安全隐患类型。 脚本可以使用强大的编程方式或动态的编程方式。 语法。 由于java的基本语法得到了扩展,并与groove样式的脚本语言特性兼容,因此plainless非常易读,并且经过了针对性的优化。 此语言是专门为elasticsearch定制的。 在一个简单的例子中,要理解这个东西,首先要看能做什么来引起兴趣。 首先,简单地看一下示例,它与各种groove、python和js没有什么不同,但请特别注意,使用强类型的编程方式会大大提高执行速度

#动态类型的写法deffirst=input.doc.first _ name.0; def last=input.doc.last_name.0; 返回第一次' '最后一次; #强类型(比上面的动态类型快10倍) stringfirst=(string ) (List ) ) (Map ) input.get (doc ) ) (first_name ) ).get string last 返回第一次' '最后一次; 具体示例将初始化数据曲棍球的一系列数据输入ES。

PUT hockey/player/_bulk? 刷新

{'index':{'_id':1}}

{'first':'johnny ',' last':'gaudreau ',' goals ' : [ 9,27,1 ],' assists ' 3360 [ 17,46,0 ]

{'index':{'_id':2}}

{'first':'sean ',' last':'monohan ',' goals ' : [ 7,54,26 ],' assists ' 3360 [ 11,26,13 ]

{'index':{'_id':3}}

{'first':'jiri ',' last':'hudler ',' goals ' : [ 5,34,36 ],' assists ' : [ 11,62,42 ]

{'index':{'_id':4}}

{'first':'micheal ',' last':'frolik ',' goals ' : [ 4,6,15 ],' assists ' 3360 [ 8,23,15 ]

{'index':{'_id':5}}

{'first':'sam ',' last':'bennett ',' goals ' : [ 5,0,0 ],' assists ' : [ 8,1,0 ],' ggals }

{'index':{'_id':6}}

{'first': '痴情魔镜',' last':'wideman ',' goals ' : [ 0,26,15 ],' asists ' : [ 11,30,24 ]

{'index':{'_id':7}}

{'f}

irst":"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":"ngdhj","last":"giordano","goals":[6,30,15],"assists":[3,30,24],"gp":[26,60,63],"born":"1983/10/03"}
{"index":{"_id":10}}
{"first":"qcdpw","last":"backlund","goals":[3,15,13],"assists":[6,24,18],"gp":[26,82,82],"born":"1989/03/17"}
{"index":{"_id":11}}
{"first":"热情的啤酒","last":"colborne","goals":[3,18,13],"assists":[6,20,24],"gp":[26,67,82],"born":"1990/01/30"}

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

用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方法。下面的例子,取每个球员是哪年出生的:

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。