上文中,说了整个es的相关度评分的算法,本文将使用四种常见的方法来优化相关度分数
query-time boost
就是之前说过的给某一个查询增加权重,语法如下1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22GET forum/article/_search
{
"query": {
"bool": {
"should": [
{
"match": {
"title": {
"query": "java spark",
"boost":2
}
}
},
{
"match": {
"content": "java spark"
}
}
]
}
}
}
给哪个match增加boost,哪个match的权重就越高,相关度评分就越高
重构查询结构
比如说一个搜索是这样的1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29GET forum/article/_search
{
"query": {
"bool": {
"should": [
{
"match": {
"content": "java"
}
},
{
"match": {
"content": "spark"
}
},
{
"match": {
"content": "solution"
}
},
{
"match": {
"content": "beginner"
}
}
]
}
}
}
这样的话,这四个match的权重是一样的,如下这样重构1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35GET forum/article/_search
{
"query": {
"bool": {
"should": [
{
"match": {
"content": "java"
}
},
{
"match": {
"content": "spark"
}
},
{
"bool": {
"should": [
{
"match": {
"content": "solution"
}
},
{
"match": {
"content": "beginner"
}
}
]
}
}
]
}
}
}
把后面的两个查询放到了一个bool中,这样的话, 下面这个bool中的两个match的权重和上面的一个match的权重是一样的
在新版的es中,这样重构查询对分数的影响越来越小了,一般不用也可以
negative boost
假如说我们要搜索包含java,不包含spark的时候, 有spark的内容是不会出来的,那么如果我们想要的结果是包含java的排在前面,包含spark的尽量排在后面,而不是直接排除掉
来看一下语法1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18GET forum/article/_search
{
"query": {
"boosting": {
"positive": {
"match": {
"content": "java"
}
},
"negative": {
"match": {
"content": "spark"
}
},
"negative_boost": 0.2
}
}
}
这样的话包含了negative term的doc,分数会乘以negative_boost,使得分数降低
constant_score
如果我们就不需要相关度评分的话,直接使用constant_score就可以了 所有的doc的分数都是1,就没有评分的概念了1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27GET forum/article/_search
{
"query": {
"bool": {
"should": [
{
"constant_score": {
"query": {
"match": {
"title": "java"
}
}
}
},
{
"constant_score": {
"query": {
"match": {
"title": "java"
}
}
}
}
]
}
}
}