如何在Elasticsearch查询中实现文档优先级排序:搜索'BANANA'时优先展示非JEANS分类的商品
解决Elasticsearch商品分类优先级排序问题
嘿,这个需求很常见,用Elasticsearch的自定义评分功能就能完美解决。核心思路就是给非JEANS分类的商品额外加权,让它们在搜索结果里更靠前。我给你两种可行的方案,你可以根据自己的实际场景选:
方案一:Function Score Query(推荐)
这种方案会兼顾关键词匹配得分和分类优先级,既保证搜索结果的相关性,又满足排序需求。完整的DSL查询如下:
{ "query": { "function_score": { // 第一步:匹配关键词"BANANA" "query": { "multi_match": { "query": "BANANA", "fields": ["attributes.value^5", "mainTaxon.name"] } }, // 第二步:给非JEANS分类的商品加权重 "functions": [ { "filter": { "bool": { "must_not": { "term": { "mainTaxon.name.keyword": "JEANS" } } } }, "weight": 2 // 权重值可根据需求调整,越大优先级越高 } ], // 权重与原始得分的计算方式:相乘 "boost_mode": "multiply" } } }
关键部分解释:
multi_match:负责匹配关键词"BANANA",这里给attributes.value(商品名称)设置了^5的权重,确保商品名称匹配的优先级高于分类名称,你可以根据业务需求调整这个数值。functions里的过滤规则:筛选出所有不是JEANS分类的商品,给它们乘以2的权重,这样这类商品的最终得分会是原始匹配得分×2,自然排在JEANS商品前面。boost_mode: "multiply":表示把原始查询得分和自定义权重相乘,这是最常用的加权模式,你也可以换成sum(得分相加)等其他模式。
方案二:脚本排序(强制优先级)
如果你希望完全忽略匹配得分,只按分类优先级排序,可以用脚本排序的方式。这种方式会先把非JEANS的商品全部排在前面,再按原始得分排序:
{ "query": { "multi_match": { "query": "BANANA", "fields": ["attributes.value^5", "mainTaxon.name"] } }, "sort": [ { "_script": { "type": "number", "script": { "source": "doc['mainTaxon.name.keyword'].value == 'JEANS' ? 1 : 0" }, "order": "asc" // 0在前,1在后 } }, "_score" // 第二步按匹配得分排序 ] }
关键部分解释:
- 脚本给JEANS分类的商品赋值1,其他分类赋值0,按升序排序后,所有非JEANS的商品会排在最前面,然后再根据原始的关键词匹配得分排序。
总结
如果你的场景需要兼顾搜索相关性和分类优先级,方案一是更好的选择;如果要求分类优先级绝对优先,不管匹配得分高低都要把非JEANS商品放在前面,就选方案二。
内容的提问来源于stack exchange,提问作者Lorenzo Ruozzi
相关产品推荐
相关产品推荐

