Elasticsearch-55-使用rescoring机制优化近似匹配的性能

match 和 phrase match(proximity match)的区别

match:只要简单的匹配到了一个term,就可以将term对应的doc返回.

phrase match:首先扫描到所有term的document list,然后对每个document都计算term position,是否符合指定的范围,slop需要进行复杂的运算,来判断是否能通过slop移动,匹配一个document

match query的性能比phrase match和proximity match要高很多,因为后两者都需要计算position的距离,match query比phrase match的性能要高10倍, 比proximity match的性能要高20倍.
但是别太担心,因为es的性能一般都在毫秒级别,match query一般就在几毫秒,或者几十毫秒,而phrase match和proximity match 的性能在几十毫秒到几百毫秒之间,也是可以接受的

优化proximity match的性能

主要思路就是:用match匹配先过滤出需要的数据,然后在用proximity match来根据距离提高doc的分数,同时proximity match只针对每个shard的分数排名的前n个document起作用,来重新调整他们的分数,这个过程称之为rescoring,重计分.因为一般的用户都会分页查询,只会看到前几页的数据,所以不需要对所有的结果都进行proximity match操作

举例

比如说有一个查询,match出来了1000个document,默认的情况下,proximity match需要对全部的document都进行一次运算,判断slop移动是否能够匹配上,然后去贡献自己的分数,但是很多情况下,match出来的这1000个doc,用户是不会全部都看到的,可能最多只会看前五页,一页10条的话,我们只需要第前50个doc去进行slop移动匹配,去贡献自己的分数即可,不需要对全部的1000个doc都去进行计算和贡献分数.

rescore重打分及其语法

就上面的例子来说,match的1000个doc其实已经有了一个分数了,proximity match前50个doc进行rescore重打分即可,让前50个doc,term距离越近的,排在越前面

语法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
GET /forum/article/_search
{
"query": {
"match": {
"content": "java spark"
}
},
"rescore":{
"window_size":50,
"query":{
"rescore_query":{
"match_phrase":{
"content":{
"query":"java spark",
"slop":50
}
}
}
}
}
}