应用背景
现在有许多商品需要在商品列表中进行排序展示,排序要求使用ES并且尽量一次性查出来,有要求如下:
- 重点商品,收藏商品,优质商品,普通商品的顺序展出
- 在同一类商品发生冲突时,按照自主产品,非自主产品进行展出(是否自主产品是一个集合,只有集合里面有7才属于自主产品,没有7则属于非自主产品)
- 如果继续发生冲突 按照商品录入时间展出
- 最后用id来进行兜底
- 优质商品首先根据商品的等级来排序,然后才走第二行
ES中使用到的字。
id (商品的序列号),
create_time(创建商品时间) ,
one_hand_commodity(是否是优质商品) ,
commodity_level , (商品等级4个级别 S,A,B,C)
commodity_list(商品属性,是否是自主产品) ,
publish_time , (商品上架时间)
难点
在这次应用中,有几个难点
1、优质商品有着自己的排序特点,不能使用sort来进行总体排序。
2、重点商品以及收藏商品需要置顶放在最高。
3、就是在原有实现方案基础上进行代码的合并
分析
在不能使用sort的情况下,以及优质商品的独特性,我们在ES官网给出了我们提示,使用得分,自定义得分以及funcationScore来实现评分排序。
由于优质商品有着独特的排序情况,我们将 one_hand_commodity(是否是优质商品)与commodity_level , (商品等级4个级别 S,A,B,C)俩字段,将他们满足优质商品同时满足商品等级的氛围不同的权重,用weight来赋值。
"function_score": {
"query": {
"term": {
"one_hand_commodity: {
"value": "1",
"boost": 1
}
}
},
"functions": [
{
"filter": {
"term": {
"commodity_level": {
"value": 1,
"boost": 1
}
}
},
"weight": 96
},
{
"filter": {
"term": {
"commodity_level": {
"value": 2,
"boost": 1
}
}
},
"weight": 48
},
{
"filter": {
"term": {
"commodity_level": {
"value": 3,
"boost": 1
}
}
},
"weight": 24
},
{
"filter": {
"term": {
"commodity_level": {
"value": 4,
"boost": 1
}
}
},
"weight": 12
}
],
"score_mode": "sum",
"boost_mode": "replace",
}
其中的score_mode 的作用是在functions所有命中的filter,都采用sum即累加的方式,而boost_mode 是整个functionScore与外面的query采用replace,替换的方式进行积分。
像 在集合中是否存在7,可以使用terms来进行命中
"function_score": {
"query": {
"bool": {
"must_not": [
{
"term": {
"commodity_list": {
"value": "7",
"boost": 1
}
}
}
],
"adjust_pure_negative": true,
"boost": 1
}
},
"functions": [
{
"filter": {
"bool": {
"must_not": [
{
"term": {
"commodity_list": {
"value": "7",
"boost": 1
}
}
}
],
"adjust_pure_negative": true,
"boost": 1
}
},
"weight": 3
}
],
"score_mode": "sum",
"boost_mode": "replace",
"boost": 1
}
而对于重点商品以及收藏商品就可以在mysql中关联查询出来,在es语句中进行赋值
"function_score": {
"query": {
"terms": {
"id": [
53507,
53628
],
"boost": 1
}
},
"functions": [
{
"filter": {
"terms": {
"id": [
53507,
53628
],
"boost": 1
}
},
"weight": 192
}
],
"score_mode": "sum",
"boost_mode": "replace",
"boost": 1
}
这样将优质商品的不同等级进行了不同的得分,最后就可以使用sort来进行排序。
"sort": [
{
"_score": {
"order": "desc"
}
},
{
"create_time": {
"order": "desc"
}
},
{
"id": {
"order": "desc"
}
}
],
ps:整个这次查询的weight设置,统一使用
前面所有weight和 < 现在需要赋值的weight
且最小只能从大于1开始,不能为1。文章来源:https://www.toymoban.com/news/detail-498510.html
附:全部查询代码文章来源地址https://www.toymoban.com/news/detail-498510.html
{
"from": 0,
"size": 10,
"query": {
"bool": {
"must": [
{
"term": {
"commodity_status": {
"value": 2,
"boost": 1
}
}
},
{
"terms": {
"id": [
53507,
53628,
53656,
53681
],
"boost": 1
}
},
{
"term": {
"is_delete": {
"value": 0,
"boost": 1
}
}
}
],
"should": [
{
"function_score": {
"query": {
"term": {
"one_hand_commodity": {
"value": "1",
"boost": 1
}
}
},
"functions": [
{
"filter": {
"term": {
"commodity_level": {
"value": 1,
"boost": 1
}
}
},
"weight": 96
},
{
"filter": {
"term": {
"commodity_level": {
"value": 2,
"boost": 1
}
}
},
"weight": 48
},
{
"filter": {
"term": {
"commodity_level": {
"value": 3,
"boost": 1
}
}
},
"weight": 24
},
{
"filter": {
"term": {
"commodity_level": {
"value": 4,
"boost": 1
}
}
},
"weight": 12
}
],
"score_mode": "sum",
"boost_mode": "replace",
"max_boost": 3.4028235e+38,
"boost": 1
}
},
{
"function_score": {
"query": {
"term": {
"one_hand_commodity": {
"value": "0",
"boost": 1
}
}
},
"functions": [
{
"filter": {
"term": {
"one_hand_commodity": {
"value": "0",
"boost": 1
}
}
},
"weight": 6
}
],
"score_mode": "sum",
"boost_mode": "replace",
"max_boost": 3.4028235e+38,
"boost": 1
}
},
{
"function_score": {
"query": {
"term": {
"commodity_list": {
"value": "7",
"boost": 1
}
}
},
"functions": [
{
"filter": {
"term": {
"commodity_list": {
"value": "7",
"boost": 1
}
}
},
"weight": 2
}
],
"score_mode": "sum",
"boost_mode": "replace",
"max_boost": 3.4028235e+38,
"boost": 1
}
},
{
"function_score": {
"query": {
"bool": {
"must_not": [
{
"term": {
"commodity_list": {
"value": "7",
"boost": 1
}
}
}
],
"adjust_pure_negative": true,
"boost": 1
}
},
"functions": [
{
"filter": {
"bool": {
"must_not": [
{
"term": {
"commodity_list": {
"value": "7",
"boost": 1
}
}
}
],
"adjust_pure_negative": true,
"boost": 1
}
},
"weight": 3
}
],
"score_mode": "sum",
"boost_mode": "replace",
"max_boost": 3.4028235e+38,
"boost": 1
}
},
{
"function_score": {
"query": {
"terms": {
"id": [
53507,
53628,
53656,
53681
],
"boost": 1
}
},
"functions": [
{
"filter": {
"terms": {
"id": [
53507,
53628,
53656,
53681
],
"boost": 1
}
},
"weight": 192
}
],
"score_mode": "sum",
"boost_mode": "max",
"max_boost": 3.4028235e+38,
"boost": 1
}
}
],
"adjust_pure_negative": true,
"boost": 1
}
},
"sort": [
{
"_score": {
"order": "desc"
}
},
{
"create_time": {
"order": "desc"
}
},
{
"id": {
"order": "desc"
}
}
],
"track_total_hits": 2147483647
}
到了这里,关于关于ES中Function_Score在自定义打分中的应用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!