背景

通过脚本改变评分

背景

近期有一个需求,需要对优惠券可用商品列表加个排序,只针对面值类的券不包括折扣券。

需求是这样的,假设有一张面值券 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 方式。

脚本默认是 groovy,当然也可以根据需要使用其他脚本语言,我们来看下实现。

script.inline: on

script.enfine.groovy.inline.aggs: on

script.indexed: on

script.file: on

首先在 es.yml 配置中打开脚本支持相关选项。

{

"query": {

"function_score": {

"query": {

"bool": {

"should": [

{

"match": {

"productName": "英语"

}

}

]

}

},

"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

}

查询条件可以任意,关键是 script_score 对象,script 是需要 ES 脚本引擎执行的脚本代码。

一个比较重要的选项 boost_mode ,boost_mode 是控制整个 document 的评分方式,这里我们选择替代(replace)默认计算好的评分。

这里面的排序有一个小技巧,如何将负数排序在前面,正数排序在后面,还有抵扣后是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;

}

通过 couponPrice 变量表示优惠券面值金额,如果当前商品抵扣完是负数说明需要排序在前面,那么如何和抵扣完正数分开尼,这里可以取一个稍微大点的值加上抵扣后的负值,这样把负值转换成正数自然就排序在前面。

抵扣后等于0的或者小于1大于0的值也是可以优先安排在前面,当然这里还是不够灵活的,最好的方式是根据当前面值、商品价格动态计算才准确。

最后就是抵扣完需要用户在额外支付的排在最后面,直接取需要额外支付的金额数值作为排序。

通过 ES 评分我们能做很多事情,这个case只是一个简单的场景。

作者:王清培 (沪江集团资深架构师)

es修改排序_ElasticSearch 评分排序相关推荐

  1. ElasticSearch源码解析(五):排序(评分公式)

    ElasticSearch源码解析(五):排序(评分公式) 转载自:http://blog.csdn.net/molong1208/article/details/50623948   一.目的 一个 ...

  2. sql多字段求和降序排序_elasticsearch基础笔记11-搜索排序

    1.默认排序 ES是按照查询和文档的相关度进行排序的,默认是降序排列,也就是说,我们之前的查询, 可以认为是下面这样子的,. 当然,我们也可以换一个字段来进行排序,那么,就不用评分了. 全文搜索也类似 ...

  3. Elasticsearch中的评分排序--Function score query

    文章目录 1. 背景 2. 数据构建 3. function score使用 3.1 function score示例 3.2 参数说明 1. 背景 实际开发中,使用elasticsearch做搜索时 ...

  4. 对后台返回的数据进行评分排序、时间排序!

    导读:对后台返回的数据进行评分排序,时间排序,可以倒序,可以正序. 按照评分排序 正序 qualityScoreSort(){this.tableData0.sort((a, b) => {re ...

  5. python爬取豆瓣读书_用python+selenium抓取豆瓣读书中最受关注图书并按照评分排序...

    抓取豆瓣读书中的(http://book.douban.com/)最受关注图书,按照评分排序,并保存至txt文件中,需要抓取书籍的名称,作者,评分,体裁和一句话评论 方法一:#coding=utf-8 ...

  6. Aimp3的播放列表 按评分排序 落雨

    如图,添加评分选项,并保存,就可以在下图的选项里找到此选项,并按评分排序 效果图如下:还可以倒置,迅速使评分高的音乐排在播放列表的前面位置!! 转自百度知道: http://zhidao.baidu. ...

  7. 用python+selenium抓取豆瓣电影中的正在热映前12部电影并按评分排序

    抓取豆瓣电影(http://movie.douban.com/nowplaying/chengdu/)中的正在热映前12部电影,并按照评分排序,保存至txt文件 1 #coding=utf-8 2 f ...

  8. 数组查找、赋值、复制、反转及修改,三种常用排序算法

    1.线性查找:通过遍历的方式,一个一个的数据进行比较.查找(具有普遍适用性).. public class ArrTest001{//线性查找public static void main(Strin ...

  9. 学生管理系统 结构体+链表(登录,注册,查询,修改,删除,排序,求平均)

    学生管理系统-使用链表(优化) # 登录,注册,查询,修改,删除,排序,求平均 转载--网络资源 #include<stdio.h> #include<string.h> #i ...

最新文章

  1. linux下tomcat6无法显示图片验证码 少了图形插件
  2. QColorDialog中Pick Screen Color、Ok、Cancel不能汉化解决
  3. zip (ICSharpCode.SharpZipLib.dll文件需要下载)
  4. RANSAC算法在图像拼接上的应用的实现
  5. 人类附身机器人获得永生_脑机接口先驱尼古莱利斯:人类无法实现数字永生
  6. C#将图片白色背景设置为透明
  7. 安全数组-简易矩阵容器-STL及迭代器仿写作业
  8. Java属性文件– java.util.Properties
  9. SuperRuntimeLibrary.TextVoice 发布,支持文本到语音 文本到.wav
  10. lcd1602c语言程序分析,全方位解析LCD1602特性及单片机显示应用
  11. arcgis面填充图案_如何将CAD里的图案填充导入ARCGIS中?
  12. 蝶形算法 matlab,FFT快速傅里叶变换(蝶形算法)详解
  13. 真假蜘蛛识别php,真假百度蜘蛛IP识别终极技巧:一学就会!
  14. Windows10系统无法更改默认浏览器等默认设置
  15. java实现微软文本转语音(TTS)经验总结
  16. speedoffice文档中怎么删除页眉页脚
  17. 欲取代Android的Firefox OS 的意外复兴
  18. FileProvider Android7.0 (文件共享,使用系统播放器打开视频等等)
  19. AD中PCB板设计中如何将正反面相互对调
  20. [转]Unity3D新手教学,让你十二小时,从入门到掌握!(一)

热门文章

  1. WPS和office有什么不同
  2. iOS中蓝牙技术的实现
  3. PC-DMIS 2019 EROWA校验夹具外部坐标系
  4. nodejs死亡笔记之CentOS7虚拟机的安装配置及nodejs的安装(面向Windows编程)
  5. 360称该工具全面保护QQ用户的安全
  6. leetcode:2463. 最小移动总距离【排序 + nmm复杂度 + 限制性dp】
  7. 一个普普通通的Windows简单开发环境搭建
  8. DIY民间蹭网利器(加强版)
  9. 【Python】爬虫-Xpath
  10. 《高频电子线路》课程参考文献