二十一、Elasticsearch使用rescore重打分机制
1、match和match_phrase(proximity match)的区别
match --》只要简单的匹配到了一个term,就可以理解将term对应的doc作为结果返回,扫描倒排索引,扫描到了就OK。
match_phrase --》首先扫描到所有term的doc list;找到包含所有term的doc list;然后对每个doc都计算每个term的position,是否符合指定的范围;
slop,需要进行复杂的运算,来判断能否通过slop移动匹配一个doc。
2、match和match_phrase(proximity match)的性能对比
match query的性能比match_phrase和proximity match(有slop)要高很多,因为后两者都要计算position的距离。
match query比match_phrase的性能要高10倍,比proximity match(带slop的)性能要高20倍。
但是无须担心,ES都在几十秒到几百毫秒之间,可以接受的。
3、优化proximity match的性能
一般优化思路是减少要进行proximity match搜索的document数量。
主要思路如下:
用match query先过滤出需要的数据,然后再用proximity match来根据term距离提高doc分数,同时proximity match只针对每个shard的分数排名前N个doc起作用,来重新调整他们的分数,这个过程称之为rescoring(重打分)。
上一篇幅说了:用match+proximity match同时实现召回率和精准度
默认情况下,match也许匹配了1000个doc,proximity match全都需要对每个doc进行一遍运算,判断能否slop移动匹配上,然后去贡献自己的分数,但是很多情况下,match出来也许1000个doc,其实用户大部分情况下是分页查询的,所以可能最多只会看前几页,比如一页是10条,最多也许就看5页,就是50条。
proximity match只要对前50条doc进行slop移动去匹配,去贡献自己的分数即可,不需要对全部1000个doc都去进行计算和贡献分数。
如下代码(rescore):
GET /forum/article/_search
{
"query": {
"match": {
"content": "java spark"
}
},
"rescore" : {
"window_size" : 50,
"query" : {
"rescore_query" : {
"match_phrase" : {
"content" : {
"query" : "java spark",
"slop" : 50
}
}
}
}
}
}
若有兴趣,欢迎来加入群,【Java初学者学习交流群】:458430385,此群有Java开发人员、UI设计人员和前端工程师。有问必答,共同探讨学习,一起进步!
欢迎关注我的微信公众号【Java码农社区】,会定时推送各种干货:
qrcode_for_gh_577b64e73701_258.jpg