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