在前面我们介绍了好几篇的打分相关的文章,在这篇里面我们再介绍一个在语义搜索里面会涉及到的定制得分function_score。这个function_score的含义就是,可以为相关的搜索条件进行定制打分,这个定制打分的规则由我们用户自定义。本篇文章我们还是按照案例的方式给大家介绍。
function_score的使用语法如下:
{ "query": { "function_score": { "query": {}, "functions": [] } } }
这就是使用function_score定制得分进行查询的基础语法,我们需要在functions里面定义自己的逻辑。下面举个例子:
首先准备一些文档
1、Have a nice day. 2、It's not my day! 3、save sth. for a rainy day
此时我们有这样一个需求,需要搜索day,但是文档里面包含save的我们希望增加他的权重,此时使用定制得分的效果如下:
post /xxx/_search { "query": { "function_score": { "query": { "match": { "description": { "query": "day" } } }, "functions": [ { "filter": { "match": { "description": "save" } }, "random_score": {}, "weight": 2 } ] } } }
我们在查询functions里面添加了一个filter,如果匹配上save,那么提高当前文档的权重。此时在返回结果里面,第三条信息就会自动往前排序。
下面我们详细介绍下载functions里面自定义functions的时候使用到的函数:
一、weight函数
weight函数是非常简单的,它主要是将得分乘以一个常数。最终提高得分,示例就是:
{ "query": { "function_score": { "query": { "match": { "description": { "query": "day" } } }, "functions": [ { "filter": { "match": { "description": "save" } }, "random_score": {}, "weight": 2 } ] } } }
二、field_value_factor函数
这个函数是看起来其实也相当于为某个字段添加一个boost一样的效果,使用方法如下:
{ "query": { "function_score": { "query": { "match": { "description": { "query": "day" } } }, "functions": [ { "field_value_factor": { "field": "title", //标记对应的字段 "factor": 2, //乘以当前的系数 "modifier": "ln" //这里可选,有:ln,none,log,log1p,log2p,ln1p,ln2p,square,sqrt,reciprocal } } ] } } }
三、script_score脚本函数
脚本函数其实就是通过脚本的方式让用户完全的控制该如下修改得分。这里的脚本一般都是使用Groovy语言编写的。例如:
{ "query": { "function_score": { "query": { "match": { "description": { "query": "day" } } }, "functions": [ { "script_score": { "script": "Math.log(doc['title'].values.size() * otherscore)", //将在每一篇匹配的文档上运行此脚本计算得分 "params": { "otherscore": 2 //上面脚本的变量参数 } } } ], "boost_model": "replace" //替换掉初始的文档得分,也就是所有的打分都是由脚本计算获取,初始打分不再生效 } } }
四、random_score随机函数
给文档指定随机分数,这种方式主要是尽量使用户看到的每一次搜索结果不一样。也就是打分是随机的,因此排序的结果也是随机的。例如:
{ "query": { "function_score": { "query": { "match": { "description": { "query": "day" } } }, "functions": [ { "random_score": { "seed": 123 //基数种子 } } ] } } }
五、衰减函数
衰减函数可以指定某个字段,然后这个字段的分数逐渐衰减。举个例子可以很容易理解,例如我们想要统计某个地理位置的数据,那我们可以使用衰减原函数对靠近某个地理点的结果增加得分,远离这个地理点的结果逐渐减少得分。这样在查询的时候距离越近,得分越高,排在最前面。是不是很实用?再举个场景,再排序统计加过里面,我们总数越多,可以使用衰减函数增加得分,总数越少,可以使用衰减函数减少得分,这样总数多的都会排在前面。在衰减函数里面主要有三种,分别是:
1、linear 2、gauss 3、exp
使用的语法是:
"functions": [ { "${TYPE}": { ////这里的type是 linear、gauss、exp取一种即可 "${字段}": { //索引里面的字段 "origin": "10", "offset": "0", "scale": "5", "decay": "0.2" //衰退倍率 } } } ]
例如:
{ "query": { "function_score": { "query": { "match": { "description": { "query": "day" } } }, "functions": [ { "gauss": { "location": { "origin": { //定位某个点 "lat":50.541243, "lng": 1.187845 }, "offset": "2km", //距离中心点2公里内都是满分,从2公里开始衰减 "scale": "5km", //衰减率 "decay":"0.2" } } } ] } } }
我们挨个介绍下这几个参数
1)origin
这是曲线的中心点,我们一般希望这里的中心点的分数是最高的。
2)offset
这是指分数开始衰减的位置,主要是距离中心点的距离。
3)scale和decay。
scale可以理解成我们设置的一个最远距离,与decay行程一个配比关系。像上面的案例,我们设置的scale是5km,代表的就是距离中心点5公里的位置,结合decay设置的0.2,代表的含义是距离中心点5公里的地方,分数应该是远点分数的0.2倍。
最后我们再给一个使用各种定制得分规则的一个完整案例
{ "query": { "function_score": { "query": { "match": { "description": { "query": "day" } } }, "functions": [ { "filter": { "match": { "description": "save" } }, "random_score": {}, "weight": 2 }, { "field_value_factor": { "field": "title", "factor": 2, "modifier": "ln" } }, { "gauss": { "location": { "origin": { "lat": 50.541243, "lng": 1.187845 }, "offset": "2km", "scale": "5km", "decay": "0.2" } } } ], "score_mode": "sum", "boost_mode": "replace" } } }
还没有评论,来说两句吧...