近期有乙個需求,需要對優惠券可用商品列表加個排序,只針對面值類的券不包括折扣券。
需求是這樣的,假設有一張面值券 50 塊錢,可用商品列表 a 100、b 40、c 10,當使用者查詢當前券可用商品列表的時候優先將卡券可以直接抵扣且不需要使用者在額外支付的商品排在前面。
c 10其實排序有很多側重,比如:b 40
a 100
1.根據使用者利益最大化原則,排序列表應該是 b、c、a這裡暫且先不擴充套件如何對商品列表進行智慧型排序,如果需要完整的個性化商品推薦,涉及很多東西,後面有經驗在拿來分享。2.根據使用者購買習慣,有可能是 a、b、c
3.根據運營策略、第三方利益等有可能是c、b、a
我們就這個簡單的 case,一開始最直接的想法就是加個排序列,建索引的時候將排序值計算好直接寫入。後來分析了下原來索引(index) 結構不是這種笛卡爾積的排列,所以在短時間內很難立馬上線,需要新建index結構。
後來通過討論用影響評分的方法來解決,可以節省時間快速上線。
es query dsl支援很多種型別的查詢,結果的排序如果沒有特殊宣告sort field則是根據es打分(score)來排序的,score分值越高排序越靠前。
es score計算比較複雜,涉及到tf(詞頻)/idf(逆向文件頻率)、罕見詞、匹配文件長度、權重 boost向量空間模型等,不過es提供了幾種封裝好的評分外掛程式供使用。
function_score查詢來讓我們根據業務場景改變文件評分方法,根據業務場景我們需要完全控制score生成的邏輯,所以我們選擇script_score方式。
script_score指令碼預設是groovy,當然也可以根據需要使用其他指令碼語言,我們來看下實現。如果需求超出以上範圍時,用自定義指令碼可以完全控制評分計算,實現所需邏輯。
(參考:
script.inline: on
script.enfine.groovy.inline.aggs: on
script.indexed: on
script.file: on
首先在 es.yml 配置中開啟指令碼支援相關選項。
}]
}},
"score_mode": "first",
"script_score": ,
"script": "def deduct = couponprice - doc['unitcost'].value.tofloat(); if (deduct > 0) else if(deduct==0 || (deduct<1 && deduct>0))else"
},"boost_mode": "replace"}},
"from": 0,
"size": 100
}
查詢條件可以任意,關鍵是script_score物件,script是需要es指令碼引擎執行的指令碼**。
乙個比較重要的選項boost_mode,boost_mode是控制整個document的評分方式,這裡我們選擇替代(replace)預設計算好的評分。
這裡面的排序有乙個小技巧,如何將負數排序在前面,正數排序在後面,還有抵扣後是0的處理。
def deduct = couponprice - doc['unitcost'].value.tofloat();
if (deduct > 0) else if(deduct==0 || (deduct<1 && deduct>0))else
通過 couponprice 變數表示優惠券面值金額,如果當前商品抵扣完是負數說明需要排序在前面,那麼如何和抵扣完正數分開尼,這裡可以取乙個稍微大點的值加上抵扣後的負值,這樣把負值轉換成正數自然就排序在前面。
抵扣後等於0的或者小於1大於0的值也是可以優先安排在前面,當然這裡還是不夠靈活的,最好的方式是根據當前面值、商品**動態計算才準確。
最後就是抵扣完需要使用者在額外支付的排在最後面,直接取需要額外支付的金額數值作為排序。
通過 es 評分我們能做很多事情,這個case只是乙個簡單的場景。
ElasticSearch的評分計算
elasticsearch 搜素時會帶有乙個 score 的資料,表示搜尋出來的結果與引數之間的相關性 elasticsearch 的三大評分原則 elasticsearch 了解為什麼這樣評分 elasticsearch 的文字評判基礎演算法 5.0 以前使用 tf idf 演算法 5.0 以後使...
Elasticsearch相關度評分 score
是為了將當前查詢的結果進行排序,比較不同查詢結果的相關度評分沒有太大意義。score q,d score q,d 是文件 d 與查詢 q 的相關度評分。querynorm q 查詢歸一化因子,用來使查詢結果之間能夠相互比較,但意義不大,因為 score的目的並不是對不同查詢進行比較,而是用來對查詢結...
elasticsearch在評分相同的情況下排序
公司產品提出需求,需要對文件進行評分,如果評分不相同則按照評分大小排序,如果評分相同則在相同的結果下按照試題年份排序.es在執行sort之後方評分失效 通過閱讀文件得知,es在執行評分會大量耗時,並且在排序的時候由於沒有指定元欄位 score 會導致不會進行評分.所以我們在使用的時候如果想根據評分相...