真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Elasticsearch評(píng)分排序-創(chuàng)新互聯(lián)

Elasticsearch 評(píng)分排序
  • 背景
  • 通過(guò)腳本改變?cè)u(píng)分
背景

近期有一個(gè)需求,需要對(duì)優(yōu)惠券可用商品列表加個(gè)排序,只針對(duì)面值類的券不包括折扣券。

成都創(chuàng)新互聯(lián)公司服務(wù)項(xiàng)目包括民勤網(wǎng)站建設(shè)、民勤網(wǎng)站制作、民勤網(wǎng)頁(yè)制作以及民勤網(wǎng)絡(luò)營(yíng)銷策劃等。多年來(lái),我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢(shì)、行業(yè)經(jīng)驗(yàn)、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,民勤網(wǎng)站推廣取得了明顯的社會(huì)效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到民勤省份的部分城市,未來(lái)相信會(huì)繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!

需求是這樣的,假設(shè)有一張面值券 50 塊錢,可用商品列表 A 100、B 40、C 10,當(dāng)用戶查詢當(dāng)前券可用商品列表的時(shí)候優(yōu)先將卡券可以直接抵扣且不需要用戶在額外支付的商品排在前面。

C 10
B 40
A 100

其實(shí)排序有很多側(cè)重,比如:

1.根據(jù)用戶利益大化原則,排序列表應(yīng)該是 B、C、A
2.根據(jù)用戶購(gòu)買習(xí)慣,有可能是 A、B、C
3.根據(jù)運(yùn)營(yíng)策略、第三方利益等有可能是C、B、A

這里暫且先不擴(kuò)展如何對(duì)商品列表進(jìn)行智能排序,如果需要完整的個(gè)性化商品推薦,涉及很多東西,后面有經(jīng)驗(yàn)在拿來(lái)分享。

我們就這個(gè)簡(jiǎn)單的 case,一開始最直接的想法就是加個(gè)排序列,建索引的時(shí)候?qū)⑴判蛑涤?jì)算好直接寫入。后來(lái)分析了下原來(lái)索引(index) 結(jié)構(gòu)不是這種笛卡爾積的排列,所以在短時(shí)間內(nèi)很難立馬上線,需要新建index結(jié)構(gòu)。

后來(lái)通過(guò)討論用影響評(píng)分的方法來(lái)解決,可以節(jié)省時(shí)間快速上線。

通過(guò)腳本改變?cè)u(píng)分

ES query DSL支持很多種類型的查詢,結(jié)果的排序如果沒(méi)有特殊聲明sort field則是根據(jù)es打分(score)來(lái)排序的,score分值越高排序越靠前。

ES score計(jì)算比較復(fù)雜,涉及到TF(詞頻)/IDF(逆向文檔頻率)、罕見詞、匹配文檔長(zhǎng)度、權(quán)重 boost向量空間模型等,不過(guò)ES提供了幾種封裝好的評(píng)分插件供使用。

function_score查詢來(lái)讓我們根據(jù)業(yè)務(wù)場(chǎng)景改變文檔評(píng)分方法,根據(jù)業(yè)務(wù)場(chǎng)景我們需要完全控制score生成的邏輯,所以我們選擇script_score方式。

script_score
如果需求超出以上范圍時(shí),用自定義腳本可以完全控制評(píng)分計(jì)算,實(shí)現(xiàn)所需邏輯。
(參考:https://www.elastic.co/guide/cn/elasticsearch/guide/current/function-score-query.html)

腳本默認(rèn)是groovy,當(dāng)然也可以根據(jù)需要使用其他腳本語(yǔ)言,我們來(lái)看下實(shí)現(xiàn)。

script.inline: on
script.enfine.groovy.inline.aggs: on
script.indexed: on
script.file: on

首先在 es.yml 配置中打開腳本支持相關(guān)選項(xiàng)。

{
    "query": {
        "function_score": {
            "query": {
                "bool": {
                    "should": [
                        {
                            "match": {
                                "productName": "英語(yǔ)"
                            }
                        }
                    ]
                }
            },
            "score_mode": "first",
            "script_score": {
                "lang": "groovy",
                "params": {
                    "couponPrice": 100
                },
                "script": "def deduct = couponPrice - doc['unitCost'].value.toFloat(); if (deduct > 0) {return 10000 + deduct;}else if(deduct==0 || (deduct<1 && deduct>0)){return 20000;}else{return  doc['unitCost'].value.toFloat()-couponPrice;}"
            },
            "boost_mode": "replace"
        }
    },
    "from": 0,
    "size": 100
}

查詢條件可以任意,關(guān)鍵是 __script_score對(duì)象,script是需要ES__ 腳本引擎執(zhí)行的腳本代碼。

一個(gè)比較重要的選項(xiàng)boost_mode,boost_mode是控制整個(gè)document的評(píng)分方式,這里我們選擇替代(replace)默認(rèn)計(jì)算好的評(píng)分。

這里面的排序有一個(gè)小技巧,如何將負(fù)數(shù)排序在前面,正數(shù)排序在后面,還有抵扣后是0的處理。

def deduct = couponPrice - doc['unitCost'].value.toFloat(); 
if (deduct > 0) {
    return 10000 + deduct; 
}else if(deduct==0 || (deduct<1 && deduct>0)){
    return 20000; 
}else{
    return  doc['unitCost'].value.toFloat()-couponPrice;
}

通過(guò) couponPrice 變量表示優(yōu)惠券面值金額,如果當(dāng)前商品抵扣完是負(fù)數(shù)說(shuō)明需要排序在前面,那么如何和抵扣完正數(shù)分開尼,這里可以取一個(gè)稍微大點(diǎn)的值加上抵扣后的負(fù)值,這樣把負(fù)值轉(zhuǎn)換成正數(shù)自然就排序在前面。

抵扣后等于0的或者小于1大于0的值也是可以優(yōu)先安排在前面,當(dāng)然這里還是不夠靈活的,最好的方式是根據(jù)當(dāng)前面值、商品價(jià)格動(dòng)態(tài)計(jì)算才準(zhǔn)確。

最后就是抵扣完需要用戶在額外支付的排在最后面,直接取需要額外支付的金額數(shù)值作為排序。

通過(guò) ES 評(píng)分我們能做很多事情,這個(gè)case只是一個(gè)簡(jiǎn)單的場(chǎng)景。

作者:王清培 (滬江集團(tuán)資深架構(gòu)師)

名稱欄目:Elasticsearch評(píng)分排序-創(chuàng)新互聯(lián)
本文URL:http://weahome.cn/article/dcssep.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部