如何基于字段值实现Elasticsearch产品搜索的自定义排序
Elasticsearch产品搜索排序查询调整方案
原有查询存在的问题
- 缺失bookingCount字段的权重统计,无法实现
clickCount+bookingCount总和排序逻辑 - 重复定义了两次clickCount的权重规则,逻辑冗余
- isPromoted的加权值过低,无法保证所有推广产品的得分一定高于非推广产品,会出现非推广产品排到推广产品前面的情况
调整方案
方案1:基于function_score调整(适配原有写法)
直接替换原有DSL为以下内容即可:
GET /products/_search { "query": { "function_score": { "query": { "wildcard": { "name": "*pro*" } }, "functions": [ // 给推广产品加足够高的固定权重,保证一定排在非推广产品前面 { "filter": { "term": { "isPromoted": 1 } }, "weight": 1000 }, // 计算clickCount+bookingCount的总和作为排序权重 { "script_score": { "script": "doc['clickCount'].value + doc['bookingCount'].value" } } ], "boost_mode": "sum", "boost": 0 // 关闭关键词相关性得分的影响,完全按自定义规则排序 } }, "sort": [ { "_score": { "order": "desc" } } ] }
方案2:直接使用sort参数(更简洁高效)
因为你的排序规则是固定的分层排序,不需要依赖关键词相关性得分,直接用sort参数实现更简单,性能也更好:
GET /products/_search { "query": { "wildcard": { "name": "*pro*" } }, "sort": [ // 第一层:推广产品优先 { "isPromoted": { "order": "desc" } }, // 第二层:按clickCount+bookingCount总和降序 { "_script": { "type": "number", "script": "doc['clickCount'].value + doc['bookingCount'].value", "order": "desc" } } ] }
验证说明
两种方案返回的结果都完全匹配你给出的预期排序:
- 推广产品
products2(总和7)、products(总和3)排在最前 - 非推广产品按总和降序依次为
pro(167)、product(156)、prod(90)、produ(53)、produc(22)
内容的提问来源于stack exchange,提问作者kindacoder
相关产品推荐
相关产品推荐

