首先這個特性處于實驗階段矿咕,在之后發(fā)布的release版本中可能會被移除悦荒,Elastic官方會盡最大努力去修復(fù)可能出現(xiàn)的各種問題春锋,因為不受GA保護(hù)累贤,所以前期大家盡量不要在生產(chǎn)環(huán)境中使用
1、介紹
script_score 是 function score 2.0版本屹耐, 允許用戶在檢索中靈活修改文檔score尸疆,來實現(xiàn)自己干預(yù)結(jié)果排名的目的,另外script score性能要高于function score
下面我們通過一個簡單的例子來加深理解惶岭,通過script score將文檔score值修改為“l(fā)ike”字段值的十分之一:
GET /_search
{
"query" : {
"script_score" : {
"query" : {
"match": { "message": "elasticsearch" }
},
"script" : {
"source" : "doc['likes'].value / 10 "
}
}
}
}
2寿弱、操作
-
在script 中訪問當(dāng)前文檔_score值
用戶可以在script中訪問變量_score ,還是上面的例子,我們給當(dāng)前score加上“l(fā)ike”值:
{
"query" : {
"script_score" : {
"query" : {
"match": { "message": "elasticsearch" }
},
"script" : {
"source" : "doc['likes'].value + _score "
}
}
}
}
-
Vector查詢支持
這類查詢目前有cosineSimilarity 和 dotProduct兩類函數(shù)支持按灶,只能應(yīng)用在dense_vecotor 和 sparse_vector數(shù)據(jù)類型上症革。
例如,通過cosineSimilarity函數(shù)計算query文檔與索引庫里文檔的dense_vector相似度:
{
"query": {
"script_score": {
"query": {
"match_all": {}
},
"script": {
"source": "cosineSimilarity(params.queryVector, doc['my_dense_vector'])",
"params": {
"queryVector": [4, 3.4, -0.2]
}
}
}
}
}
如果是計算sparse_vector field的cosine相似度:
{
"query": {
"script_score": {
"query": {
"match_all": {}
},
"script": {
"source": "cosineSimilaritySparse(params.queryVector, doc['my_sparse_vector'])",
"params": {
"queryVector": {"2": 0.5, "10" : 111.3, "50": -1.3, "113": 14.8, "4545": 156.0}
}
}
}
}
}
再如鸯旁,在dense_vector field上計算給定文檔與索引庫文檔點積的距離時:
{
"query": {
"script_score": {
"query": {
"match_all": {}
},
"script": {
"source": "dotProduct(params.queryVector, doc['my_dense_vector'])",
"params": {
"queryVector": [4, 3.4, -0.2]
}
}
}
}
}
同理噪矛,在sparse_vector上進(jìn)行點積計算,需要使用dotProductSparse 函數(shù):
{
"query": {
"script_score": {
"query": {
"match_all": {}
},
"script": {
"source": "dotProductSparse(params.queryVector, doc['my_sparse_vector'])",
"params": {
"queryVector": {"2": 0.5, "10" : 111.3, "50": -1.3, "113": 14.8, "4545": 156.0}
}
}
}
}
}
上述vector查詢需要注意的時铺罢,如果vector field缺失數(shù)值時艇挨,或者查詢語句中vector規(guī)格與索引庫字段的vector規(guī)格不一致,那么該文檔的計算結(jié)果會是0
-
調(diào)用自定義Painless script
用戶可以靈活的使用Painless語法編寫自己的Function 韭赘,并在script中進(jìn)行調(diào)用缩滨,另外值得注意的是,本身es提供了大量的預(yù)定義Function可供調(diào)用辞居,這些都是經(jīng)過優(yōu)化的楷怒,執(zhí)行效率比較高蛋勺。
sigmoid(value, k, a) = value^a/ (k^a + value^a)
"script" : {
"source" : "sigmoid(doc['likes'].value, 2, 1)"
}
-
對數(shù)字類型字段添加衰減函數(shù)
常用到的衰減函數(shù)有decayNumericLinear(線性)瓦灶,decayNumericExp(指數(shù)),decayNumericGauss(高斯)
"script" : {
"source" : "decayNumericLinear(params.origin, params.scale, params.offset, params.decay, doc['dval'].value)",
"params": {
"origin": 20,
"scale": 10,
"decay" : 0.5,
"offset" : 0
}
}
-
對geo類型字段添加衰減函數(shù)
常用到的衰減函數(shù)有decayGeoLinear(線性)抱完,decayGeoExp(指數(shù))贼陶,decayGeoGauss(高斯)
"script" : {
"source" : "decayGeoExp(params.origin, params.scale, params.offset, params.decay, doc['location'].value)",
"params": {
"origin": "40, -70.12",
"scale": "200km",
"offset": "0km",
"decay" : 0.2
}
}
-
對日期類型字段添加衰減函數(shù)
常用到的衰減函數(shù)有decayDateLinear(線性),decayDateExp(指數(shù))巧娱,decayDateGauss(高斯)碉怔,不支持 mow 函數(shù)。
"script" : {
"source" : "decayDateGauss(params.origin, params.scale, params.offset, params.decay, doc['date'].value)",
"params": {
"origin": "2008-01-01T01:00:00Z",
"scale": "1h",
"offset" : "0",
"decay" : 0.5
}
}
需要注意的是上述幾個衰減函數(shù)中都用到了params參數(shù)禁添,而該參數(shù)官方說明是不支持動態(tài)改變數(shù)值的撮胧,個人覺得不是很好用,后期應(yīng)該還會優(yōu)化
- Function Score 轉(zhuǎn) Script Score
script_score:function score中的script_score 函數(shù)部分不需要進(jìn)行修改老翘,可以直接拷貝到script score里運行芹啥。
weight:
"script" : {
"source" : "params.weight * _score",
"params": {
"weight": 2
}
}
random_score:
"script" : {
"source" : "randomNotReproducible()"
}
field_value_factor:
"script" : {
"source" : "Math.log10((doc['field'].size() == 0 ? 1 : doc['field'].value()) * params.factor)",
params" : {
"factor" : 5
}
}
其中 Math.log10((doc['field'].size() == 0 是為了排除因field missing引起的異常锻离,field_value_factor 里modifier(權(quán)重調(diào)控函數(shù))可以通過下面函數(shù)實現(xiàn):
名稱 | 實現(xiàn) |
---|---|
none | - |
log | Math.log10(doc['f'].value) |
log1p | Math.log10(doc['f'].value + 1) |
log2p | Math.log10(doc['f'].value + 2) |
ln | Math.log(doc['f'].value) |
ln1p | Math.log(doc['f'].value + 1) |
ln2p | Math.log(doc['f'].value + 2) |
square | Math.pow(doc['f'].value, 2) |
sqrt | Math.sqrt(doc['f'].value) |
reciprocal | 1.0 / doc['f'].value |