Elasticsearch-62-用function_score自定义相关度分数算法

function_score

我们可以自定义一个function_score函数,自己将某个field的值,跟es内置算出来的分数进行运算,然后由自己制定的field来进行分数的增强

准备测试数据

给所有帖子增加follower数量

1
2
3
4
5
6
7
8
9
10
11
POST /forum/article/_bulk
{ "update": { "_id": "1"} }
{ "doc" : {"follower_num" : 5} }
{ "update": { "_id": "2"} }
{ "doc" : {"follower_num" : 10} }
{ "update": { "_id": "3"} }
{ "doc" : {"follower_num" : 25} }
{ "update": { "_id": "4"} }
{ "doc" : {"follower_num" : 3} }
{ "update": { "_id": "5"} }
{ "doc" : {"follower_num" : 60} }

案例

将对帖子搜索得到的分数,和follower_num进行运算,由follower_num在一定程度上增强帖子的分数

比如我们有一个这样的搜索请求

1
2
3
4
5
6
7
8
9
GET /forum/article/_search
{
"query": {
"multi_match": {
"query": "java spark",
"fields": ["content","title"]
}
}
}

然后现在用function_score来对分数进行增强

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
GET /forum/article/_search
{
"query": {
"function_score": {
"query": {
"multi_match": {
"query": "java spark",
"fields": ["content","title"]
}
},
"field_value_factor": {
"field": "follower_num",
"modifier": "log1p",
"factor" : 0.5
},
"boost_mode": "sum",
"max_boost": 2
}
}
}

先看一下这段搜索请求,是在之前的query的下一层包了一层function_score.

参数详解

field_value_factor

field_value_factor中,如果只有field,那么会将每个doc的分数都乘以follower_num,如果有的doc的follower_num是0,那么分数也会变为0,效果不好,因此一般还会设置一个modifier属性,加一个log1p函数,加了这个函数以后,公式会变为: new_score = old_score log(1 + number_of_votes),这样算出来的分数是比较合理的
后面还有个factor参数,可以进一步影响分数,公式会变为new_score = old_score
log(1 + factor * number_of_votes)

boost_mode

可以决定分数与指定字段是如何计算的,默认的是乘法(multiply), 也可以指定 sum,min,max,replace

max_boost

限制计算出来的分数不要超过max_boost指定的值,但是在新版的es中作用不大