function_score 內容較多,此篇主要是介紹 function_score 的基本概念
具體實例請參考以下連接
ElasticSearch - function_score(field_value_factor 具體實例)
ElasticSearch - function_score(weight 具體實例)
在使用 ES 進行全文搜索時,搜索結果默認會以文檔的相關度進行排序,而這個 “文檔的相關度”,是可以透過 function_score 自己定義的,也就是說我們可以透過使用 function_score,來控制 “怎麼樣的文檔相關度更高” 這件事
_score
的 DSL,它允許爲每個主查詢 query 匹配的文檔應用加強函數, 以達到改變原始查詢評分 score 的目的function_score 提供了幾種加強 _score
計算的函數
weight
: 設置一個簡單而不被規範化的權重提升值
new_score = old_score * 2
field_value_factor
: 將某個字段的值乘上 old_score
new_score = old_score * 那個文檔的 likeCount 的值
random_score
: 爲每個用戶都使用一個不同的隨機評分對結果排序,但對某一具體用戶來說,看到的順序始終是一致的衰減函數 (linear、exp、guass)
: 以某個字段的值為基準,距離某個值越近得分越高script_score
: 當需求超出以上範圍時,可以用自定義腳本完全控制評分計算,不過因為還要額外維護腳本不好維護,因此盡量使用 ES 提供的評分函數,需求真的無法滿足再使用 script_scorefunction_scroe其他輔助的參數
boost_mode
: 決定 old_score 和 加強score 如何合併
new_score = old_score * 加強score
new_score = old_score + 加強score
new_score = min(old_score, 加強score)
new_score = max(old_score, 加強score)
new_score = 加強score
score_mode
: 決定 functions 裡面的加強 score 們怎麼合併,會先合併加強 score 們成一個總加強 score,再使用總加強 score 去和 old_score 做合併,換言之就是會先執行 score_mode,再執行 boost_mode
max_boost
: 限制加強函數的最大效果,就是限制加強 score 最大能多少,但要注意不會限制 old_score
加強score = min(加強score, max_boost)
function_score 查詢模板
如果要使用 function_score 改變分數,要使用 function_score 查詢
簡單的說,就是在一個 function_score 內部的 query 的全文搜索得到的 _score
基礎上,給他加上其他字段的評分標準,就能夠得到把 “全文搜索 + 其他字段” 綜合起來評分的效果
單個加強函數的查詢模板
GET mytest/doc/_search
{
"query": {
"function_score": {
//主查詢,查詢完後這裡自己會有一個評分,就是 old_score
"query": {.....},
//在 old_score 的基礎上,給他加強其他字段的評分
//這裡會產生一個加強 score,如果只有一個加強 function 時,直接將加強函數名寫在 query 下面就可以了
"field_value_factor": {...},
//指定用哪種方式結合 old_score 和加強 score 成為 new_score
"boost_mode": "multiply",
//限制加強 score 的最高分,但是不會限制 old_score
"max_boost": 1.5
}
}
}
多個加強函數的查詢模板
如果有多個加強函數,那就要使用functions來包含這些加強函數們,functions是一個數組,裡面放著的是將要被使用的加強函數列表
可以為functions裡的加強函數指定一個filter,這樣做的話,只有在文檔滿足此filter的要求,此filter的加強函數才會應用到文擋上,也可以不指定filter,這樣的話此加強函數就會應用到全部的文擋上
一個文檔可以一次滿足多條加強函數和多個filter,如果一次滿足多個,那麼就會產生多個加強score,因此ES會使用score_mode定義的方式來合併這些加強score們,得到一個總加強score,得到總加強score之後,才會再使用boost_mode定義的方式去和old_score做合併
像是下面的例子,field_value_factor和gauss這兩個加強函數會應用到所有文檔上,而weight只會應用到滿足filter的文檔上,假設有個文檔滿足了filter的條件,那他就會得到3個加強score,這3個加強score會使用sum的方式合併成一個總加強score,然後才和old_score使用multiply的方式合併
GET mytest/doc/_search
{
"query": {
"function_score": {
//主查詢,查詢完後這裡自己會有一個評分,就是 old_score
"query": {.....},
//可以有多個加強函數(或是 filter + 加強函數)
//每一個加強函數會產生一個加強 score,因此 functions 會有多個加強 score
"functions": [
{ "field_value_factor": ... },
{ "gauss": ... },
{ "filter": {...}, "weight": ... }
],
//決定加強 score 們怎麼合併成一個總加強 score
"score_mode": "sum",
//決定總加強 score 怎麼和 old_score 合併
"boost_mode": "multiply"
}
}
}
不要執著在調整 function_score 上