[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 脚本编程

ElasticSearch实战(三十四)-Painless 脚本编程

[ElasticSearch]painless脚本使用方式及性能比较