一 序
本文屬於極客時間Elasticsearch核心技術與實戰學習筆記系列。
在使用Elasticsearch進行全文搜索的時候,默認是使用BM25計算的_score字段進行降序排序的。
- ES 默認會以文檔的相關度算分進行排序
- 可以通過制定一個或者多個字段進行排序
- 使用相關性算分(score)排序,不能滿足某些特定條件
- 無法針對相關度,對排序實現更多的控制
二 Function Score Query
Function Score Query
- 可以在查詢結束後,對每一個匹配的文檔進行一系列的重新算分,根據新生成的分數進行排序
提供了幾種默認的計算分值的函數
- Weight:爲每一個文檔設置一個簡單而不被規範化的權重
- Field Value Factor:使用該數值來修改_score,例如將 “熱度” 和 “點贊數” 作爲算分的參考因素
- Random Score:爲每一個用戶使用一個不同的,隨機算分結果
2.1 demo按受歡迎度提升權重
- 希望能夠將點贊多的 blog,放在搜索列表相對靠前的位置。同事搜索的評分,還是要作爲排序的主要依據
- 新的算分 = 老的算分 * 投票數
- 投票數爲 0
- 投票數很大時
數據準備:
PUT /blogs/_doc/1
{
"title": "About popularity",
"content": "In this post we will talk about...",
"votes": 0
}
PUT /blogs/_doc/2
{
"title": "About popularity",
"content": "In this post we will talk about...",
"votes": 100
}
PUT /blogs/_doc/3
{
"title": "About popularity",
"content": "In this post we will talk about...",
"votes": 1000000
}
其中數據的title,content 都是一樣的,只是投票數差別很大。下面使用:field_value_factor:考慮到vote數量。
可以看到,票數高的分數遙遙領先。
2.2使用 Modifier 平滑曲線
再來看看field_value_factor內的一些參數
field
相乘的字段,該字段必須是數字類型。
factor
相乘的係數,可以自己調節相乘的係數
missing
定義字段缺省值
modifier
剛纔的例子,差異性巨大,可以使用modifier修正字段值.下面是官網的介紹:
This table lists how field_value_factor
modifiers can be implemented through a script:
Modifier | Implementation in Script Score |
---|---|
|
- |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
可以看到,用了順序不變,但是分數差距不大了。
當factor和modifier同時使用的時候,factor優先於modifier
2.3 Boost Mode 和 Max Boost
Boost Mode
- Multiply:算分和函數值的乘積
- Sum:算分和函數值的和
- Min/Max:算分與函數去 最小 / 最大值
- Replace:使用函數取代算分
Max Boost 可以將算分控制在一個最大值
當我們使用field_value_factor和functions內簡單的weight無法滿足業務的時候,可以使用Elasticsearch提供的Painless腳本來自定義排序函數,這個老師沒有展開,感興趣的看下官網的介紹吧。
2.4 一致性隨機函數
可以讓不同的人請求得到不同的排序結果,而同一個人請求可以得到相同的結果。
es 7.0 之後,參數有兩個:
seed
指定隨機的種子,相同的種子返回相同排序,每個種子會爲每個文檔生成一個0-1的隨機數,改隨機數就是random_score的返回值,可以和其他filter或者外部打分一起使用。
field
對於相同shard的相同field的值,產生的隨機數一樣,因此在使用的時候,儘量選擇值不一樣的field。