好久沒有寫更新了,有灰!再次抱歉!!!前端時間一直在研究kubernets+.net core相關,本打算寫幾篇k8s的文章,但在公司聽到同事遇到個需求一直沒有搞定,於是出於程式設計師的本能了解了一下,就是需要根據左上角,右下角的經緯度坐標查詢一批在地圖上均勻分布!
一、先看語法
_search{ "query":{ "function_score":{ "query":{ "match_all":{} }, "functions":[ { "gauss":{ "location":{ "origin":{ "lon":116.402688, "lat":39.91416 }, "offset":"5km", "scale":"10km" } } } ], "boost_mode":"replace", "score_mode":"sum", "max_boost":10, "min_score":1 "boost":5 } }}二、也支持僅帶一個函數的語法如
GET /_search{
"query": {
"function_score": {
"query": { "match_all": {} },
"boost": "5",
"random_score": {},
"boost_mode": "multiply"
}
}}三、下面介紹下3種decay functions衰減函數
gauss:高斯函數則是鐘形的,他的衰減速率是先緩慢,然後變快,最後又放緩
linear:線性函數是條直線,一旦直線與橫軸0相交,所有其他值的評分都是0
exp:指數函數是先劇烈衰減然後變緩
具體效果圖參考官網:
https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-function-score-query.html#function-decay
四、random_scoring隨機一致性函數,可以隨用戶而變,官方示例:
GET /_search{
"query": {
"function_score": {
"random_score": {
"seed": 10,
"field": "_id" //_seq_no文檔修改時會變,建議使用一個文檔的唯一值欄位
}
}
}}五、field_value_factor函數,直接指定field有時可能太多生硬了,可以通過modifier和factor參數配合使結果更加柔和些,modifier可以有更多函數可用(log,log1p,log2p,ln,ln1p,ln2p,sqrt,square,none,reciprocal)
GET /_search{
"query": {
"function_score": {
"field_value_factor": {
"field": "my-int",
"factor": 1.2,
"modifier": "sqrt",
"missing": 1
}
}
}}六、script_score 通過腳本(painless-默認、expression等)完全自定義控制評分計算,如官網直接使用文檔的值作為結果
GET /_search{
"query": {
"function_score": {
"query": {
"match": { "message": "elasticsearch" }
},
"script_score": {
"script": {
"source": "Math.log(2 + doc['my-int'].value)"
}
}
}
}}七、最後我們看一個實戰案例,這個也是困擾我們公司很久的一個小問題,當然我們自己對elasticsearch的了解也很有限,場景是我們希望在地圖上通過小紅點的方式展示我們的門店,每個門店有經緯度位置,當地圖放大時查詢一批門店,在地圖上均勻分布,就這麼個需求!
來我們看看如何搞定它!就用到我們這裡的random_score函數,當然我這裡使用了script_fields計算距離以及根據距離排序,僅僅為了演示這種功能而已!
{ "size":15, "_source":"*", "sort":[ { "_geo_distance":{ "location":[116.402688,39.91416], "order":"asc", "unit" : "km", "ignore_unmapped": true } } ], "script_fields":{ "distance":{ "script":{ "lang":"painless", "source":"doc['location'].arcDistance(params.lat,params.lon) * 0.001", "params":{ "lon":116.402688, "lat":39.91416 } } } }, "query":{ "function_score":{ "query":{ "match_all":{}//這裡加上你自己的查詢條件 }, "functions":[{ "random_score":{ "seed":10, "field":"_id" } }], "boost_mode":"sum" } }}