阅读本文需要先了解function_score的相关知识,请看 ElasticSearch - function_score 简介
首先准备数据和索引,在ES插入三笔数据,其中title是text类型,like是integer类型(代表点赞量)
{ "title": "ES 入门", "like": 2 } { "title": "ES 进阶", "like": 5 } { "title": "ES 最高难度", "like": 10 }
先使用一般的query,查看普通的查询的评分会是如何
GET 127.0.0.1/mytest/doc/_search { "query": { "match": { "title": "ES" } } }
"hits": [ { "_score": 0.2876821, "_source": { "title": "ES 入门", "like": 2 } }, { "_score": 0.20309238, "_source": { "title": "ES 进阶", "like": 5 } }, { "_score": 0.16540512, "_source": { "title": "ES 最高难度", "like": 10 } } ]
使用function_score 的 field_value_factor改变
_score
,将old_score乘上like的值本来 "ES最高难度" 的score是0.16540512,经过field_value_factor的改变,乘上了那个文档中的like值(10)之后,新的score变为 1.6540513
GET 127.0.0.1/mytest/doc/_search { "query": { "function_score": { "query": { "match": { "title": "ES" } }, "field_value_factor": { "field": "like" } } } }
"hits": [ { "_score": 1.6540513, //原本是0.16540512 "_source": { "title": "ES 最高难度", "like": 10 } }, { "_score": 1.0154619, //原本是0.20309238 "_source": { "title": "ES 进阶", "like": 5 } }, { "_score": 0.5753642, //原本是0.2876821 "_source": { "title": "ES 入门", "like": 2 } } ]
加上max_boost,限制field_value_factor的最大加强score
可以看到ES入门的加强score是2,在max_boost限制裡,所以不受影响
而ES进阶和ES最高难度的field_value_factor函数产生的加强score因为超过max_boost的限制,所以被设为3
GET 127.0.0.1/mytest/doc/_search { "query": { "function_score": { "query": { "match": { "title": "ES" } }, "field_value_factor": { "field": "like" }, "max_boost": 3 } } }
"hits": [ { "_score": 0.6092771, //原本是0.20309238 "_source": { "title": "ES 进阶", "like": 5 } }, { "_score": 0.5753642, //原本是0.2876821 "_source": { "title": "ES 入门", "like": 2 } }, { "_score": 0.49621537, //原本是0.16540512 "_source": { "title": "ES 最高难度", "like": 10 } } ]
有时候线性的计算
new_score = old_score * like值
的效果并不是那麽好,field_value_factor中还支持 modifier、factor 参数,可以改变like值对old_score的影响modifier参数支持的值
none :
new_score = old_score * like值
默认状态就是none,线性
log1p :
new_score = old_score * log(1 + like值)
最常用,可以让like值字段的评分曲线更平滑
log2p :
new_score = old_score * log(2 + like值)
ln :
new_score = old_score * ln(like值)
ln1p :
new_score = old_score * ln(1 + like值)
ln2p :
new_score = old_score * ln(2 + like值)
square : 计算平方
sqrt : 计算平方根
reciprocal : 计算倒数
factor参数
factor作为一个调节用的参数,没有modifier那麽强大会改变整个曲线,他仅改变一些常量值,设置factor>1会提昇效果,factor<1会降低效果
假设modifier是log1p,那麽加入了factor的公式就是
new_score = old_score * log(1 + factor * like值)
对刚刚的例子加上 modifier、factor
GET 127.0.0.1/mytest/doc/_search { "query": { "function_score": { "query": { "match": { "title": "ES" } }, "field_value_factor": { "field": "like", "modifier": "log1p", "factor": 2 } } } }
就算加上了modifier,但是 "全文评分 与 field_value_factor函数值乘积" 的效果可能还是太大,我们可以通过参数
boost_mode
来决定 old_score 和 加强score 合併的方法如果将boost_mode改成sum,可以大幅弱化最终效果,特别是使用一个较小的factor时
加入了boost_mode=sum、且factor=0.1的公式变为
new_score = old_score + log(1 + 0.1 * like值)
GET 127.0.0.1/mytest/doc/_search { "query": { "function_score": { "query": { "match": { "title": "ES" } }, "field_value_factor": { "field": "like", "modifier": "log1p", "factor": 0.1 }, "boost_mode": "sum" } } }