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 } } } } } }