您好,登錄后才能下訂單哦!
function_score 配合 script_score 是排序的終極方案
例子:
curl -XGET 'http://localhost:9200/*/*/_search?pretty&explain' -d '{
"size" : 0,
"query" : {
"function_score" : {
"query" : {
"filtered" : {
"filter" : {
"bool" : {
"must" : {
"match" : {
"_all" : {
"query" : "關鍵字",
"type" : "boolean",
"operator" : "AND"
}
}
}
}
}
}
},
"functions" : [ {
"script_score" : {
"params": {
"field": "company_name",
"term": "關鍵字"
},
"script" : "_index[field][term].df()"
}
} ,
{
"filter" : {
"match" : {
"company_name" : {
"query" : "關鍵字",
"type" : "boolean",
"operator" : "AND"
}
}
},
"weight" : 2
}
],
"score_mode" : "sum"
}
},
"aggregations" : {
"agg" : {
"terms" : {
"field" : "member_id",
"size" : 0,
"order" : {
"top_hit" : "desc"
}
},
"aggregations" : {
"top_hit" : {
"max" : {
"script" : {
"inline" : "_score"
}
}
}
}
}
}
}'
需要配置:
script.engine.groovy.inline.search: on
script.inline: on
script.indexed: on
script_score可以讓你更加靈活的操作ES的打分。例如
"script_score" : {
"params": {
"field": "company_name",
"terms": ["關鍵字"]
},
"script" : "score = 0.0; queryLength = 0.0; docLength = 0.0; for (word in terms) { tf = _index[field][word].tf(); score = score + tf * 1.0; queryLength = queryLength + 1.0; docLength = docLength + pow(tf, 2.0); }; return (float)score /(sqrt(docLength) * sqrt(queryLength)); "
}
這里需要注意的是 company_name 這個字段 不允許分詞,否則這個近似算法可能有問題,個人感覺script_score 執行的時間比較靠后,此時分詞階段已經結束,company_name 已經被分詞完畢,不是源表中的值了,所以這個字段不能分詞。 這里例子實際意義不大,但是看到function_score 還是很強大的。
當上面的query內容變成如下內容時:
"match" : {
"_all" : {
"query" : "關鍵字",
"type" : "boolean",
"operator" : "AND"
}
}
相關×××開始啟用。打出的分數算法如下。
score=(weight+script_score)*相關性分數
而原來的寫法,打分就是 _index[field][term].df()+weight 的值,因為相關性在filter下都是1。
下面舉例來說明
4.09 是相關性的分數,
6.09=2+4.09 其中 4.09 來自下面的配置, 很明顯_score=4.09 因為上面已經提到了。
"script_score" : {
"script" : "return _score"
}
所以:score=(weight+script_score)*相關性分數。
至于相關性的分數如何打出,也很類似,請自行查看資料學習
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。