介绍
介绍
控制Elasticsearch搜索引擎的查询结果的评分的终极武器script_score,评分完全的自定义化,真的是想怎么玩就怎么玩,爽的不要不要的。
福哥今天会给大家讲讲如何使用ES的script_score去自定义查询结果的每个文档的评分,完完全全地按照自己的想法去设计文档的评分计算方法。
script_score
按照官方的说法,使用script_score可以通过Groovy脚本编写一个函数,用来计算文档的评分。在这个函数里面可以访问文档的全部字段以及文档的默认评分,甚至还可以访问词频和逆向文档频率(不过福哥没有找到示例)。
Groovy是一个用来给Java程序做单元测试的辅助脚本,它和JavaScript非常相似,大家可以很容易上手的。
公式计算评分
假设福哥给同福网的文章搜索设计一个自定义评分逻辑,将文章的访问量作为一个加权的考量,将访问量除以10000次的商作为增幅去扩大默认评分的值,计算公式如下:
_score * ((doc['mReadC'].value + 0.0) / 100 + 1)
应用到ES的query里,需要将script_score放到function_score里面,因为script_score是function_score的一种方式,具体到上面的例子就是这个样子的:
{ "from": 0, "size": 10, "query": { "function_score": { "query": { "bool": { "must": [ { "match": { "mTitle": { "query": "java", "minimum_should_match": "80%", "boost": 6 } } } ] } }, "script_score": { "script": { "source": "_score * (doc['mReadC'].value / 10000 + 1)" } } } } }
函数计算评分
函数计算和公式计算区别就是可以支持更为复杂的逻辑,福哥设计了一个简单的逻辑,如果加权超过2倍则无论加权是多少倍都按2倍计算,函数如下:
float readC = doc['mReadC'].value; float readCRate = readC / 10000 + 1; if (readCRate > 2) { return _score * 2; } return _score * readCRate;
应用到ES的query里,需要将函数的换行符去掉,或者换成“\n”,因为JSON格式要求这样,具体的例子如下:
{ "from": 0, "size": 10, "query": { "function_score": { "query": { "bool": { "must": [ { "terms": { "mStat": [ 1 ] } }, { "bool": { "should": [ { "match": { "mTitle": { "query": "java", "minimum_should_match": "80%", "boost": 6 } } }, { "match": { "content": { "query": "java", "minimum_should_match": "100%", "boost": 1 } } } ] } } ] } }, "script_score": { "script": { "source": "float readC = doc['mReadC'].value; float readCRate = readC \/ 10000 + 1; if (readCRate > 2) { return _score * 2; } return _score * readCRate;" } } } } }
总结
今天福哥给童鞋们讲解了Elasticsearch的script_score的使用技巧,通过script_score可以完全地对查询结果里面的文档的评分进行自定义设计,这个可以帮助我们提高用户体验。