match
和phrase match(proximity match)
区别match
—> 只要简单的匹配到了一个term
,就可以理解将term
对应的doc
作为结果返回,扫描倒排索引,扫描到了就okphrase match
—> 首先扫描到所有term
的doc list
; 找到包含所有term
的doc list
; 然后对每个doc
都计算每个term
的position
,是否符合指定的范围; slop
,需要进行复杂的运算,来判断能否通过slop
移动,匹配一个docmatch query
的性能比phrase match
和proximity match
(有slop)要高很多。因为后两者都要计算position
的距离。match query
比phrase match
的性能要高10倍,比proximity match
的性能要高20倍。
但是别太担心,因为es的性能一般都在毫秒级别,match query
一般就在几毫秒,或者几十毫秒,而phrase match
和proximity match
的性能在几十毫秒到几百毫秒之间,所以也是可以接受的。
优化proximity match
的性能,一般就是减少要进行proximity match
搜索的document
数量。主要思路就是,用match query
先过滤出需要的数据,然后再用 proximity match
来根据term
距离提高doc
的分数,同时proximity match
只针对每个shard
的分数排名前n
个doc
起作用,来重新调整它们的分数,这个过程称之为rescoring
,重计分。因为一般用户会分页查询,只会看到前几页的数据,所以不需要对所有结果进行proximity match
操作。
用我们刚才的说法,match + proximity match
同时实现召回率和精准度
默认情况下,match
也许匹配了1000个doc
,proximity match
全都需要对每个doc
进行一遍运算,判断能否slop
移动匹配上,然后去贡献自己的分数
但是很多情况下,match
出来也许1000个doc,其实用户大部分情况下是分页查询的,所以可能最多只会看前几页,比如一页是10条,最多也许就看5页,就是50条
proximity match
只要对前50个doc
进行slop
移动去匹配,去贡献自己的分数即可,不需要对全部1000
个doc
都去进行计算和贡献分数
问题:如果只对前面 50
个 doc
进行 slop
移动匹配,有没有可能后面 950
个 doc
在进行 slop
移动匹配后更加的精准呢?
rescore
:重打分match
:1000
个doc
,其实这时候每个doc
都有一个分数了; proximity match
,前50
个doc
,进行rescore
,重打分,即可; 让前50
个doc
,term
举例越近的,排在越前面
GET /forum/_search
{
"query": {
"match": {
"content": "java spark"
}
},
"rescore": {
"window_size": 50,
"query": {
"rescore_query": {
"match_phrase": {
"content": {
"query": "java spark",
"slop": 50
}
}
}
}
}
}
https://www.cnblogs.com/gmhappy/p/11864048.html