[ElasticSearch]painless脚本使用方式及性能比较
Posted 小鱼收藏夹
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[ElasticSearch]painless脚本使用方式及性能比较相关的知识,希望对你有一定的参考价值。
一.3种常见方式
- doc['fieldname']: 常用于在搜索或排序等无状态操作时进行使用
- params['_source']['fieldname']:也是常用在搜索或排序中,但更多用在获取额外字段时灵活操作时使用,如不获取某个字段直接使用params['_source']获取整个_source对象;
- ctx._source:一般用于状态化操作(会已知整个文档并进行操作时),比如在进行_update_by_query或者updae等修改删除操作时,大部分都能且只能使用ctx._source。 在我看来它更像是已知结果,并对结果进行缓冲区留存而后对其进行操作,而非上述两位预设程序,并进行获取的感觉(个人拙见)
二.doc['fieldname']与params['_source']['fieldname']对比
一般在进行查询时并需要对字段进行额外获取值,并利用值进行无状态化操作时,更推荐使用此方式;
例如在script_fields中,可以同时使用doc['fieldname']及params['_source']['fieldname']的方式。
但需要注意的是:
1.通过doc['fieldname']获取字段,将会加载该字段的相关术语及字段值本身;
2.通过params['_source']['fieldname']获取字段会获取到整个_source的json对象并从中获取字段,相比第1种,此种方式会相对较慢;但如果你想对整个_source的json对象进行操作,那当我没说;尽情使用params['_source']吧
举例常用script_field及script_sort
GET test_index/_search
"script_fields":
"my_doubled_field":
"script":
"source": "doc['my_field'].value * params['multiplier']",
"params":
"multiplier": 2
GET test_index/_search
"query":
"match_all":
,
"sort": [
"_script":
"type": "number",
"order": "desc",
"script":
"lang": "painless",
"source": "doc['public_time'].value"
]
"query":
"match_all":
,
"sort": [
"_script":
"type": "number",
"order": "desc",
"script":
"lang": "painless",
"source": "params['_source']['public_time']"
]
简单结论:修改删除ctx._source,查询排序doc['fieldname']
elsearch搜索引擎 + painless脚本语言入门
最近项目用到了elsearch,ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎。
自从版本6.0之后,其默认脚本语言变为 painless 。
painless作为一门脚本语言,起语言风格跟js很类似。
es 安装 :
解压 编译安装
es 命令:
su elsearch (普通用户才能启动)
./elasticsearch -d (重启)
我们首先做个测试,插入2条数据:
put http://172.19.12.249:9200/indextest0193/player/_bulk?refresh
{"index":{"_id":1}}
{"content" : "测试语句1"}
{"index":{"_id":2}}
{"content" : "我的测试语句2"}
post http: //172.19.12.249: 9200/indextest0193/_search{ "query": { "function_score": { "query": { "match": { "content": "测" } }, "script_score": { "script": { "lang": "painless", "source": "if(doc[‘content.keyword‘].value.startsWith(params.keyword))return 1; return 0;", "params": { "keyword": "测" } } }, "boost_mode": "sum" } } }
上面例子是 传入参数keyword,搜索如果匹配到keyword 则返回1,否则为0。
如果是多个字段进行打分:
def create_time=0; if(params.gender-doc[‘timestamp‘].value>2592000){ create_time = 0; }else{ create_time=(2592000+doc[‘timestamp‘].value-params.gender)*30/2592000 } def level=0; if(doc[‘recommend_diff‘].value==4){ level=30 }else if(doc[‘recommend_diff‘].value==3){ level=22.5 }else if(doc[‘recommend_diff‘].value==2){ level=15 }else if(doc[‘recommend_diff‘].value==1){ level=7.5 }else if (doc[‘recommend_diff‘].value==0) { level=0 } return create_time+level;
其中gender是我传的参数,其他则是字段索引。最后 return 2个分数,用 + 进行连接。注意的是 source里面如果用双引号,那么里面
函数之间不能有空格!!! 调试可以在kibana里面调试。
附kibana截图:
以上是关于[ElasticSearch]painless脚本使用方式及性能比较的主要内容,如果未能解决你的问题,请参考以下文章
Elasticsearch painless脚本中使用java自定义类函数
Elasticsearch如何在 Elasticsearch 中轻松编写脚本
Elasticsearch如何在 Elasticsearch 中轻松编写脚本
ElasticSearch实战(三十四)-Painless 脚本编程