Elasticsearch 函數分數查詢

October 25, 2025

使用 function_score 函數分數查詢,允許去修改查詢所檢索到的文件的分數。

函數分數簡介

  • 支援多種計算方式,也可以自訂算式。
  • 可以合併全文查詢一起使用。

各種選項的說明如下:

選項 說明
weight
可搭配 filter,為特定關鍵字增加分數。
random_score
- 用於產生隨機結果。
- 例如有多筆原始分數相同的結果,可以隨機排序,常用於商品查詢上 (讓類似商品都有曝光的機會)。
- 產生 0 ~ 1 之間的隨機小數。
- 可以透過 seed  和 field  欄位,產生可複製的隨機結果。


decay function
(衰減函數)
- 適用地理位置、數值、日期等差距計算。
- 分為 Gauss, Linear, Exp 三種。
- 數字介於 0 ~ 1 之間。
- decay : 衰減分數。
- scale : 衰減程度。
- offset : 以 origin 為中心,在偏移量內都是 1 分。
- origin : 中心點。


field_value_factor
可用來增減數值欄位的權重。支援多種計算方式,詳細的計算方式請參考官方說明。
boost_mode 
可以調整 ,設定查詢分數和函數分數要如何結合,例如相加、相乘。
score_mode 
可以設定各函數之間的結合方式。

可參考:Function score query - Elasticsearch Guide [8.14] - Elastic (有詳細的計算範例)。

script_score: 自訂計算函數

可以使用 script_score 方法自訂計算的公式,script 可以使用 Elasticsearch 專用的 Painless 語法,

但是寫太多奇怪的 script,會導致 Elasticsearch 查詢的速度變慢,因此 script 的內容應該保持精簡。

Painless 的語法可以在 Painless Guide - Painless Scripting Language [8.15] - Elastic 找到說明,想要找到更詳細的語法,如數學計算方法 (ex. Math.log() ),可以參考 Shared API for package java.lang - Painless Scripting Language [8.15] - Elastic 網頁。另外有幾個撰寫時的小訣竅:

  1. Painless 語法長度最長為 65,536 個字元,其說明與如何提升計算速度的網頁在 Scripts, caching, and search speed - Elasticsearch Guide [8.15] - Elastic
  2. 將變數寫在 params 內,有助於將計算方式快取起來。如果 script 常常變動,就無法快取,而減低查詢效率。
  3. 由於 JSON 不支援換行,因此必須將所有 Script 寫在同一行內。不過在 Kibana 的 Dev Tools 內,可以搭配 “”” 符號輸入多行文字。
  4. Elasticsearch 另外推薦使用特化的 Script Score 查詢代替 Fucntion Score,內有詳細的 Script 撰寫說明,詳情可參考 Script score query - Elasticsearch Guide [8.15] - Elastic

自訂某個字詞的權重

如果有某個詞在查詢時特別重要,可以在搜尋時,用 ^  在特定字詞後方加入權重,例如:

the women^2 went to the beach

參考資料:Modification of term weight - Elastic Stack / Elasticsearch - Discuss the Elastic Stack

參考資料