Elasticsearch核心技术与实战学习笔记 33 | 综合排序:Function Score Query优化算分

一 序

本文属于极客时间Elasticsearch核心技术与实战学习笔记系列。  

在使用Elasticsearch进行全文搜索的时候,默认是使用BM25计算的_score字段进行降序排序的。

  • ES 默认会以文档的相关度算分进行排序
  • 可以通过制定一个或者多个字段进行排序
  • 使用相关性算分(score)排序,不能满足某些特定条件
    • 无法针对相关度,对排序实现更多的控制

二 Function Score Query

Function Score Query

  • 可以在查询结束后,对每一个匹配的文档进行一系列的重新算分,根据新生成的分数进行排序

提供了几种默认的计算分值的函数

  • Weight:为每一个文档设置一个简单而不被规范化的权重
  • Field Value Factor:使用该数值来修改_score,例如将 “热度” 和 “点赞数” 作为算分的参考因素
  • Random Score:为每一个用户使用一个不同的,随机算分结果

2.1 demo按受欢迎度提升权重

  • 希望能够将点赞多的 blog,放在搜索列表相对靠前的位置。同事搜索的评分,还是要作为排序的主要依据
  • 新的算分 = 老的算分 * 投票数
    • 投票数为 0
    • 投票数很大时

数据准备:

PUT /blogs/_doc/1
{
  "title":   "About popularity",
  "content": "In this post we will talk about...",
  "votes":   0
}

PUT /blogs/_doc/2
{
  "title":   "About popularity",
  "content": "In this post we will talk about...",
  "votes":   100
}

PUT /blogs/_doc/3
{
  "title":   "About popularity",
  "content": "In this post we will talk about...",
  "votes":   1000000
}

其中数据的title,content 都是一样的,只是投票数差别很大。下面使用:field_value_factor:考虑到vote数量。

可以看到,票数高的分数遥遥领先。

2.2使用 Modifier 平滑曲线

再来看看field_value_factor内的一些参数

field

相乘的字段,该字段必须是数字类型。

factor

相乘的系数,可以自己调节相乘的系数

missing

定义字段缺省值

 modifier

刚才的例子,差异性巨大,可以使用modifier修正字段值.下面是官网的介绍:

This table lists how field_value_factor modifiers can be implemented through a script:

Modifier Implementation in Script Score

none

-

log

Math.log10(doc['f'].value)

log1p

Math.log10(doc['f'].value + 1)

log2p

Math.log10(doc['f'].value + 2)

ln

Math.log(doc['f'].value)

ln1p

Math.log(doc['f'].value + 1)

ln2p

Math.log(doc['f'].value + 2)

square

Math.pow(doc['f'].value, 2)

sqrt

Math.sqrt(doc['f'].value)

reciprocal

1.0 / doc['f'].value

可以看到,用了顺序不变,但是分数差距不大了。

当factor和modifier同时使用的时候,factor优先于modifier

2.3 Boost Mode 和 Max Boost

Boost Mode

  • Multiply:算分和函数值的乘积
  • Sum:算分和函数值的和
  • Min/Max:算分与函数去 最小 / 最大值
  • Replace:使用函数取代算分

Max Boost 可以将算分控制在一个最大值

当我们使用field_value_factor和functions内简单的weight无法满足业务的时候,可以使用Elasticsearch提供的Painless脚本来自定义排序函数,这个老师没有展开,感兴趣的看下官网的介绍吧。

2.4 一致性随机函数

可以让不同的人请求得到不同的排序结果,而同一个人请求可以得到相同的结果。

es 7.0 之后,参数有两个:

seed

指定随机的种子,相同的种子返回相同排序,每个种子会为每个文档生成一个0-1的随机数,改随机数就是random_score的返回值,可以和其他filter或者外部打分一起使用。

 field

对于相同shard的相同field的值,产生的随机数一样,因此在使用的时候,尽量选择值不一样的field。

猜你喜欢

转载自blog.csdn.net/bohu83/article/details/106832267