Elasticsearch function score query 自定義相關性得分

摘要

function_score將允許您修改由系統計算的匹配文檔的相關性得分。例如,如果分數函數在計算上很費時,並且足以在過濾後的文檔集上計算分數,則此功能很有用。
用戶必須聲明一個匹配項、一個或多個方程,這些函數爲查詢返回的每個文檔計算一個新分數。

請求參數

函數名 score_mode參數 boost_mode參數
max 使用最高分 查詢分數和功能分數的最大值
replace 僅使用功能分數,查詢分數將被忽略
first 具有匹配過濾器的第一個函數被應用
multiply 分數相乘(默認) 查詢分數和功能分數相乘(默認)
avg 分數是平均值 平均
sum 分數相加 查詢分數和功能分數相加
min 使用最低分數 查詢分數和功能分數的最小值

首先,通過定義的方程對每個文檔評分。score_mode指定如何組合計算出的分數。
由於分數可以處於不同的等級,並且由於有時希望函數對分數有不同的影響,因此可以使用用戶定義的權重weight來調整每個函數的分數。可以爲每一個函數設置相應的權重,乘以相應的函數計算分數。如果沒有其他任何函數聲明的情況下給出權重,則權重充當僅返回權重的函數lambda weight: weight)。
如果"score_mode":"avg",則相關性得分是各個相關性得分的加權平均數。例如,如果兩個函數返回得分1和2以及它們各自的權重是3和4,那麼他們的分數將被組合爲 (1*3+2*4)/(3+4) 而不是 (13+24)/2。

通過設置max_boost參數,可以將計算得到的分數設置爲不超過設定值。默認值爲FLT_MAX

該參數boost_mode定義,新計算的分數與查詢分數合併。
默認情況下,修改分數不會更改匹配的文檔。要排除不符合特定分數閾值的文檔,min_score可以將參數設置爲所需分數閾值。意思是說,文檔得分小於min_score設定值的話,會被過濾掉。

score functions 計算分數的函數

script score 腳本函數
weight 權重

這種方程,是將原來的分數乘以權重,得到新的分數。

random 隨機

random_score,隨機產生0,1之間的值。默認情況下,它採用內部的Lucene的文檔ID作爲隨機種子,這是非常有效的,但不幸的是不可再現的,因爲文檔可能通過合併重新編號分數。
如果你希望分數是可以複製的,可以提供seed和field。然後基於種子,所考慮文檔的field的最小值,另外根據索引名稱和分片ID計算的鹽來計算最終分數,以便具有相同值的但存儲在不同索引中的文檔得到不同的結果分數。請注意,位於相同分片內具有相同的文檔將獲得相同的分數,因此通常希望使用對所有文檔都具有唯一值的字段。一個好的默認選擇是使用_seq_no字段,其唯一的缺點是,如果文檔被更新,則分數會改變,因此更新操作也會更新_seq_no字段的值。
可以在不設置字段的情況下設置種子,但是已棄用該方法,因爲這需要在_id消耗大量內存的字段上加載字段數據。

Field Value factor

這個field_value_factor方程允許您使用文檔中的字段來影響得分。它類似於使用該script_score函數,但是它避免了腳本編寫的開銷。如果用於多值字段,則在計算中僅使用該字段的第一個值。
例如,假設您有一個用數字likes 字段索引的文檔,並希望通過該字段影響文檔的分數,則示例如下所示:
下列命令等價於:sqrt(1.2 * doc['likes'].value)

GET /_search
{
    "query": {
        "function_score": {
            "field_value_factor": {
                "field": "likes",
                "factor": 1.2,
                "modifier": "sqrt",
                "missing": 1
            }
        }
    }
}

field_value_factor有許多選項:

參數 含義
modifier 修改適用於該字段的值,可以是一個:none,log, log1p,log2p,ln,ln1p,ln2p,square,sqrt,或reciprocal。默認爲none。
field 要從文檔中提取的字段。
factor 字段值乘以的可選因子,默認爲1。
修飾符 含義
ln 取字段值的自然對數。因爲此函數將返回負值,並且如果將其用於0到1之間的值,則會導致錯誤,因此建議改用它ln1p。
reciprocal 報答字段值,同1/x那裏x是該字段的值
log1p 將1加到字段值並取對數
sqrt 取字段值的平方根
square 對字段值求平方(乘以它本身)
log 取字段值的常用對數。因爲此函數將返回負值,並且如果將其用於0到1之間的值,則會導致錯誤,因此建議改用它log1p。
ln1p 將1加到欄位值並取自然對數
ln2p 將2加到字段值上並取自然對數
log2p 在字段值上加2並取公共對數
none 不要對字段值應用任何乘數

missing參數,如果文檔沒有指定的字段,則使用這個值。就像從文檔中讀取一樣,修飾符和因數任然使用於它。

field_value_score函數產生的分數必須爲非負數,否則將引發錯誤。的logln如果在所使用的值0和1之間一定要限制的字段的值與一系列過濾器,以避免這種情況,或使用改性劑會產生負值log1p和 ln1p。

請記住,將log()設爲0或負數的平方根是非法操作,並且將引發異常。爲避免這種情況,請務必使用範圍過濾器限制該字段的值,或使用 log1pln1p

Decay function 衰減功能

衰減函數對文檔進行評分,該函數的衰減取決於文檔的數字字段值與用戶給定原點的距離。這類似於範圍查詢,但具有平滑的邊緣而不是框。
要在具有數字字段的查詢上使用距離記分,用戶必須爲每個字段定義一個origin和scale。origin來定義從中心計算距離的“中心點”,scale來聲明衰減率。
如果文檔中缺少數字字段,該函數將返回1。

  1. DECAY_FUNCTION取值:linearexpgauss
  2. FIELD_NAME類型:數字,日期,地理位置
參數 含義
origin 用於計算距離的原點。對於數字字段,必須指定爲數字;對於日期字段,必須指定爲日期;對於地理字段,必須指定爲地理點。地理位置和數字字段必填。對於日期字段,默認值爲now。原點支持日期數學(例如now-1h)。
decay decay參數定義如何在處給定的距離處對文檔進行評分scale。如果decay未定義,則遠處的文檔 scale得分爲0.5。
offset 如果offset定義了,衰減函數將僅計算距離大於定義的文檔的衰減函數 offset。默認值爲0。
scale 所有類型均必需。定義到原點的距離+偏移,計算出的分數將等於該距離decay。對於地理字段:可以定義爲數字+單位(1km,12m,…)。默認單位是米。對於日期字段:可以定義爲數字+單位(“ 1h”,“ 10d”,…。)。默認單位是毫秒。對於數字字段:任何數字。

DECAY_FUNCTION參數

參數 含義
gauss 正常衰減
exp 指數衰減
linear 線性衰減

如果用於計算衰減的字段包含多個值,則默認情況下將選擇最接近原點的只來確定距離。用multi_value_mode來定義

參數值 含義
min 距離是最小距離
max 距離是最大距離
sum 距離是所有距離的總和
avg 距離是平均距離
"DECAY_FUNCTION": { 
    "FIELD_NAME": { 
          "origin": "11, 12",
          "scale": "2km",
          "offset": "0km",
          "decay": 0.33
    },
    "multi_value_mode": "avg"
}

使用場景

單個功能
GET /_search
{
    "query": {
        "function_score": {
            "query": { "match_all": {} },
            "boost": "5",
            "random_score": {}, 
            "boost_mode":"multiply"
        }
    }
}
組合幾個功能

可以組合幾個功能。在這種情況下,可以選擇僅在文檔與給定的過濾查詢匹配時才應用功能
每個函數的過濾查詢所產生的分數並不重要。

GET /_search
{
    "query": {
        "function_score": {
          "query": { "match_all": {} },
          "boost": "5", 
          "functions": [
              {
                  "filter": { "match": { "test": "bar" } },
                  "random_score": {}, 
                  "weight": 23
              },
              {
                  "filter": { "match": { "test": "cat" } },
                  "weight": 42
              }
          ],
          "max_boost": 42,
          "score_mode": "max",
          "boost_mode": "multiply",
          "min_score" : 42
        }
    }
}

衰減功能使用示例

假設您正在尋找某個城鎮的酒店。您的預算有限。另外,您希望酒店離市中心很近,因此酒店距離理想位置越遠,您入住的可能性就越小。

您希望根據距市中心的距離以及價格來對與您的條件相匹配的查詢結果(例如“酒店,南希,不吸菸者”)進行評分。

直觀地講,您想將市中心定義爲起點,也許您願意從酒店步行2公里到市中心。
在這種情況下,您的位置字段的來源爲鎮中心,範圍爲〜2km。

如果您的預算低,您可能更喜歡便宜的東西而不是昂貴的東西。對於價格字段,原點爲0歐元,小數位數取決於您願意支付的金額,例如20歐元。

在此示例中,字段可能被稱爲“價格”作爲酒店價格,而“位置”則稱爲該酒店的座標。

價格:

"gauss": { 
    "price": {
          "origin": "0",
          "scale": "20"
    }
}

位置:

"gauss": { 
    "location": {
          "origin": "11, 12",
          "scale": "2km"
    }
}

請求示例

GET /_search
{
    "query": {
        "function_score": {
          "functions": [
            {
              "gauss": {
                "price": {
                  "origin": "0",
                  "scale": "20"
                }
              }
            },
            {
              "gauss": {
                "location": {
                  "origin": "11, 12",
                  "scale": "2km"
                }
              }
            }
          ],
          "query": {
            "match": {
              "properties": "balcony"
            }
          },
          "score_mode": "multiply"
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章