在 Elasticsearch 中,function_score 可以讓我們在查詢的同時對搜索結果進行自定義評分。
function_score 提供了一系列的參數和函數讓我們可以根據需求靈活地進行設置。
近期有同學反饋,function_score 的相關參數不好理解,本文將深入探討 function_score 的核心參數和函數。
圖片
Elasticsearch 的 function_score 查詢是一種強大的工具,它可以允許我們修改文檔的基本的相關評分,讓我們在特定的應用場景下獲得更好的搜索結果。
這個功能通過提供了一組內置函數(如 script_score, weight, random_score, field_value_factor, decay functions等),以及一系列參數(如boost_mode和score_mode等)來實現。
以下是一些 function_score 可以應用的場景:
如果需要了解用戶的興趣或者行為,我們可以使用 function_score 來提升用戶可能感興趣的結果。
比如在推薦系統中,如果我們已知道用戶喜歡某個作者的文章,可以提升這個作者的文章的得分。
比如最近火熱的“羅剎海市”就被網易云音樂推薦到最前面。
圖片
如果我們需要從一個大的數據集中隨機抽樣,可以使用 random_score 函數。
這個函數會給每個文檔生成一個隨機得分,從而讓我們能夠得到隨機的搜索結果。
對于一些時間敏感的數據,比如新聞、博客文章或者論壇帖子,新的文檔通常比舊的文檔更相關。
在這種情況下,我們可以使用 decay functions(衰減函數) 來降低舊的文檔的得分。
如果我們的應用關心地理位置,比如房地產或者旅游相關的應用。
可以使用 decay functions (衰減函數)來提升接近某個地理位置的文檔的得分。
如果我們的文檔有一些字段值可以影響相關度評分,可以使用 field_value_factor (字段值因子)函數。
比如在電商場景,一個商品的銷量、評分或者評論數量可能會影響搜索結果的排序。
總的來說,function_score 提供了一種靈活的方式來滿足各種復雜的相關度評分需求。
boost_mode 決定了如何將查詢得分和函數得分進行組合。
可接受的參數有:
boost_mode | 描述 |
multiply | 查詢得分和函數得分相乘(默認值) |
sum | 查詢得分和函數得分相加 |
avg | 查詢得分和函數得分的平均值 |
first | 僅僅使用函數得分 |
max | 查詢得分和函數得分中的最大值 |
min | 查詢得分和函數得分中的最小值 |
replace | 完全替換查詢得分,只使用函數得分 |
score_mode 決定了如何處理多個函數的分數。
可接受的參數有:
score_mode | 描述 |
multiply | 各個函數得分相乘 |
sum | 各個函數得分相加(默認值) |
avg | 各個函數得分的平均值 |
first | 僅僅使用第一個函數的得分 |
max | 各個函數得分中的最大值 |
min | 各個函數得分中的最小值 |
function_score 提供了多種函數類型來進行自定義評分:
Score Function | 描述 |
script_score | 用腳本計算得分 |
weight | 簡單地修改查詢得分,不考慮字段值 |
random_score | 生成隨機得分 |
field_value_factor | 使用字段值進行計算得分 |
decay functions | 衰減函數,根據字段值的距離計算得分,越近得分越高 |
為了幫助大家更好地理解,我們將創建一個簡單的索引,插入一些文檔,并對它們執行 function_score 查詢。
假設我們有一個名為 articles 的索引,里面存儲了一些博客文章的數據,包括作者(author),標題(title),內容(content),以及這篇文章的喜歡數量(likes)。
首先,創建索引并添加一些文檔:
PUT /articles{ "mappings": { "properties": { "title": { "type": "text" }, "author": { "type": "text" }, "content": { "type": "text" }, "likes": { "type": "integer" } } }}POST /_bulk{ "index" : { "_index" : "articles", "_id" : "1" } }{ "title": "Elasticsearch Basics", "author": "John Doe", "content": "This article introduces the basics of Elasticsearch.", "likes": 100 }{ "index" : { "_index" : "articles", "_id" : "2" } }{ "title": "Advanced Elasticsearch", "author": "Jane Doe", "content": "This article covers advanced topics in Elasticsearch.", "likes": 500 }{ "index" : { "_index" : "articles", "_id" : "3" } }{ "title": "Elasticsearch Function Score Query", "author": "John Doe", "content": "This article discusses the function_score query in Elasticsearch.", "likes": 250 }
現在我們有了一些文檔,讓我們對它們執行 function_score 查詢。
GET /articles/_search{ "query": { "function_score": { "query": { "match_all": {} }, "boost": "5", "functions": [ { "script_score": { "script": { "source": "Math.log(1 + doc['likes'].value)" } } } ], "boost_mode": "multiply" } }}
上述查詢使用了 Elasticsearch 的 function_score 查詢。
它首先對 "articles" 索引中的所有文檔進行匹配(使用 match_all 查詢),然后使用一個腳本函數(script_score),該腳本會計算每個文檔的 "likes" 字段的自然對數值加一(Math.log(1 + doc['likes'].value)),然后把這個得分與原始查詢得分相乘(由于 boost_mode 被設為了 "multiply"),最終的得分再乘以5(由于 boost 被設為了 "5")。這種查詢用于根據 "likes" 字段對結果進行加權排序。
執行結果如下:
圖片
GET /articles/_search{ "query": { "function_score": { "query": { "match_all": {} }, "functions": [ { "random_score": { "field": "likes" } } ], "boost_mode": "replace" } }}
上述查詢使用 Elasticsearch 的 function_score 查詢,并配合使用 random_score 函數。random_score 函數根據 "likes" 字段的值生成一個隨機分數。
重要的是,由于沒有提供一個固定的種子(seed),所以每次執行這個查詢都會返回一個全新的隨機排序結果。
match_all 是基礎查詢,用來匹配所有文檔。然后 random_score 函數基于 "likes" 字段值生成隨機分數。
boost_mode 設為 "replace" 表示忽略基礎查詢的分數,完全使用 random_score 函數的分數作為最終結果。所以,這個查詢會在每次執行時都返回全新的隨機排序結果。
執行結果如下圖所示:
圖片
這對于一些字段很有用,比如"likes":一篇有很多"likes"的文章可能比"likes"少的文章更相關。
示例如下:
GET /articles/_search{ "query": { "function_score": { "query": { "match": { "content": "Elasticsearch" } }, "functions": [ { "field_value_factor": { "field": "likes", "factor": 1.2, "modifier": "sqrt", "missing": 1 } } ], "boost_mode": "multiply" } }}
在這個查詢中:
表示基礎查詢是在 "content" 字段中匹配包含 "Elasticsearch" 的文章。
函數用來基于 "likes" 字段的值調整查詢得分。它首先取 "likes" 字段的值,如果文檔沒有 "likes" 字段或者該字段的值為空,那么將使用 "missing" 參數指定的默認值1。然后,它將取得的值乘以 "factor" 參數指定的因子1.2。最后,它將結果進行 "modifier" 參數指定的平方根運算("sqrt")。
參數設置為 "multiply",這表示將基礎查詢的得分和 field_value_factor 函數計算得出的得分相乘,以得到最終的文檔得分。
所以,這個查詢會返回包含 "Elasticsearch" 的文章,并且文章的得分會根據 "likes" 字段的值進行調整,"likes" 值越高的文章,得分也會越高。
執行結果如下:
圖片
如果值接近某個中心點,得分就會更高。這對于日期或地理位置字段特別有用。
Elasticsearch 提供了三種衰減函數:線性(linear)、指數(exp)、和高斯(gauss)。
以下是使用 gauss 函數的一個示例:
GET /articles/_search{ "query": { "function_score": { "query": { "match": { "content": "Elasticsearch" } }, "functions": [ { "gauss": { "likes": { "origin": "100", "scale": "20", "offset": "0", "decay": 0.5 } } } ], "boost_mode": "multiply" } }}
上述執行可概括為:使用 function_score 和 gauss 函數對含有 'Elasticsearch' 的文章進行基于 'likes' 字段的高斯衰減得分調整"。
在這個查詢中:
表示基礎查詢是在 "content" 字段中匹配包含 "Elasticsearch" 的文章。
函數則是用來對 "likes" 字段的值進行高斯衰減處理。
其中,
參數 | 值 | 描述 |
origin | 100 | 期望的中心點,即 "likes" 字段的最理想值 |
scale | 20 | 表示衰減的速度,也就是距離 "origin" 值多遠時,得分會衰減到原始得分的一半 |
offset | 0 | 表示在距離 "origin" 多少的范圍內不進行衰減 |
decay | 0.5 | 表示當距離超過了 "scale" 之后,得分會以多快的速度衰減,例如 0.5 表示超過 "scale" 距離后,得分會衰減到原始得分的一半 |
參數設置為 "multiply",這表示將基礎查詢的得分和 gauss 函數計算得出的得分相乘,以得到最終的文檔得分。
所以,這個查詢會返回包含 "Elasticsearch" 的文章,并且文章的得分會根據 "likes" 字段的值進行高斯衰減處理,"likes" 值越接近100的文章,得分也會越高。
圖片
在深入了解 Elasticsearch 的 function_score 后,我們可以明顯感受到其在搜索應用中的強大作用。無論是基于特定字段值的排序,還是利用自定義腳本微調搜索結果,function_score 都能發揮其出色的性能。
盡管 function_score 的參數和選項多樣,初看可能會覺得復雜,但只需理解各參數的含義和作用,我們就能根據需求靈活運用。實際案例中,我們使用了 script_score、field_value_factor、random_score 和 decay functions 等函數,演示了如何通過 function_score 滿足復雜的搜索需求。
但是,我們也必須注意,在使用 function_score 時,要慎重考慮性能問題,因為復雜的函數和腳本可能占用大量計算資源。在實際應用中,我們應始終關注這一點,以維護良好的系統性能。
此外,隨著數據和用戶行為的不斷變化,我們需要持續觀察、學習和調整搜索策略,以不斷提升用戶體驗。在這個過程中,function_score 將是我們強有力的工具。
總的來說,Elasticsearch 的 function_score 是一個強大而靈活的工具,只要我們深入了解并恰當使用,就能夠挖掘其巨大的潛力,提升我們的搜索應用性能和用戶體驗。
本文鏈接:http://www.tebozhan.com/showinfo-26-132-0.html深度探索 Elasticsearch 8.X:function_score 參數解讀與實戰案例分析
聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com