关于ES中Function_Score在自定义打分中的应用

应用背景

现在有许多商品需要在商品列表中进行排序展示,排序要求使用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。

附:全部查询代码

{
  "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
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值