简介
Function score 查询
https://www.elastic.co/guide/en/elasticsearch/reference/7.3/query-dsl-function-score-query.html#query-dsl-function-score-query
可以在查询结束后,对每一个匹配的文档进行一系列的重新算分,根据新生成的分数进行排序。
在使用ES进行全文搜索时,搜索结果默认会以文档的相关度进行排序,而这个 “文档的相关度”,是可以 通过 function_score 自己定义的,也就是说我们可以通过使用function_score,来控制 “怎样的文档相 关度得分更高” 这件事。
# random代表随机, 随机范围在0-5之间生成, 可以让文档随机显示
GET /book/_search
{
"query": {
"function_score": {
"query": {
"match_all": {}
},
"boost": "5",
"random_score": {}
}
}
}
比如对 book 进行随机打分 如果没有给函数提供过滤,则等效于指定”match_all”:{}
要排除不符合特定分数阈值的文档,可以将min_score参数设置为所需分数阈值。
为了使min_score正常工作,需要对查询返回的所有文档进行评分,然后逐一过滤掉。
function_score
查询提供了几种类型的得分函数。
- script_score: 自定义脚本完全控制所需逻辑
- weight: 为每一个文档设置一个简单而不被规范化的权重
- random_score: 为每一个用户使用一个不同的,随机算分结果
- fieldvalue_factor: 使用该数值来修改 score,例如将“热度”和“点赞数”作为算分的参考因素
- decay functions: gauss, linear, exp 以某个字段的值为标准,距离某个值越近,得分越高
Field Value factor
可以使用文档中的字段来影响得分。与使用 script_score 函数类似,但是它避免了脚本编写的开销。如果用于多值字段,则在计算中仅使用该字段的第一个值
GET /book/_search
{
"query": {
"function_score": {
"field_value_factor": {
"field": "price",
"factor": 1.2,
"modifier": "sqrt"
}
}
}
}
它将转化为以下得分公式 sqrt(1.2 * doc[‘price’].value)
field_value_factor函数有许多选项:
属性 | 说明 |
---|---|
field | 要从文档中提取的字段 |
factor | 字段值乘以的值,默认为1 |
modifier | 应用于字段值的修饰符可以是以下之一: none , log ln2p , square , sqrt , or reciprocal 。默认为无 |
modifier 的取值
field_value_score函数产生的分数必须为非负数,否则将引发错误。如果在0到1之间的值上使用 log和ln修饰符将产生负值。请确保使用范围过滤器限制该字段的值以避免这种情况,或者使用 log1p 和 ln1p
random_score
随着运营团队的辛苦劳作,在线书店的用户量上来了,现在想给用户推荐一些书籍。我们当然可以上线一个推荐系统,但这个明显不是现阶段需要做的事情,我们需要尽量简单地完成这个需求。
为了满足给用户推荐书籍的需求,可以使用 random_score 算分函数来实现。需要为每一个用户推荐随机的数据,但是希望一段时间内同一个用户访问的时候,这部分内容的排序都是一样的。
random_score 算分函数的使用示例:
POST books/_search
{
"query": {
"function_score": {
"random_score": {
"seed": 81819,
"field": "_seq_no"
}
}
}
}
如上示例,当 seed 的值不变的时候,随机内容的排序结果将不会变化。需要注意的是,在使用 random_score 算分函数的时候,需要指定 seed 和 field,如果只指定 seed,需要在 _id 字段上加载 fielddata,这样将会消耗大量的内存。
一般来说,使用 “_seq_no” 作为 field 的值是比较推荐的,但是如果 seed 不变的情况下,文档被更新了,这个时候文档的 _seq_no 是会变化的,将会导致排序结果的变化。