Azure Cognitive Search:如何按相关性对SKU子对象排序
问题
现有包含SKU子对象数组的产品目录索引,执行如red t-shirt这类搜索时,需要实现以下目标:
- 返回匹配的产品文档
- 对产品内的SKU子对象按相关性排序或标记相关性,在产品卡片中优先展示最相关的SKU(类似亚马逊的展示逻辑)
- 团队正从Solr迁移,Solr的分组方案在Azure Cognitive Search中不支持,目前采用的双索引临时方案效果不佳
- 额外约束:
- 允许重构索引结构
- SKU层级有数十个额外字段需要保留
- 必须保留产品内的非相关SKU
- SKU的相关性需支持过滤、分面操作
- 需支持传统分页
可行实现方案
方案1:扁平化索引+产品维度聚合(推荐)
将原有的产品-多SKU嵌套结构拆分为扁平索引,每个文档对应一个SKU,同时保留所有产品层级的字段(如产品ID、产品名称、产品描述等)以及SKU自身的数十个字段。
核心操作:
- 索引结构设计:
- 每个文档包含:
productId(产品唯一标识)、productName、productDescription、skuId、skuColor、skuSize,以及SKU的其他自定义字段 - 对需要搜索的字段(如
skuColor、productName)设置为可搜索、可筛选、可分面
- 每个文档包含:
- 搜索与排序逻辑:
- 执行搜索时,按
red t-shirt匹配所有相关SKU文档,Azure Cognitive Search会自动为每个SKU计算相关性得分 - 使用
$groupby=productId进行产品维度聚合,同时指定$select需要返回的产品字段,以及按SKU相关性得分降序排列的SKU列表 - 通过
$top和$skip实现传统分页(分页基于聚合后的产品结果)
- 执行搜索时,按
- 保留非相关SKU:
- 聚合时,可通过额外查询(按
productId过滤)获取该产品下所有SKU,合并到结果中;或者在索引中为每个SKU添加isRelevant字段,搜索时标记匹配的SKU为true、非匹配为false,聚合时一并返回所有SKU并按isRelevant+得分排序
- 聚合时,可通过额外查询(按
优势:
- 天然支持SKU维度的过滤、分面(直接对SKU字段操作即可)
- 相关性得分精准到SKU层级,排序逻辑清晰
- 完全适配Azure Cognitive Search的原生能力,无需额外复杂逻辑
注意点:
- 索引文档量会变为原产品数×平均SKU数,需评估存储成本,但Azure Cognitive Search对大索引的支持较好
- 聚合时需合理设置
$groupby的返回字段,避免数据冗余
方案2:嵌套索引+自定义相关性标记
如果不想扁平化索引,保留原有的产品文档嵌套SKU数组的结构,可通过以下方式实现SKU排序:
核心操作:
- 索引结构优化:
- 为SKU对象添加
relevanceScore字段(类型为Edm.Double),同时确保SKU的可搜索字段(如color、size)设置为可搜索、可筛选
- 为SKU对象添加
- 搜索与后处理:
- 执行产品级搜索,获取匹配的产品文档
- 对每个产品内的SKU数组,在客户端或通过Azure Cognitive Search的自定义技能重新计算每个SKU与搜索词的相关性得分:
- 自定义技能可调用Azure Cognitive Search的搜索API,针对单个SKU的字段执行搜索,获取得分后写入
relevanceScore - 客户端侧可通过简单的匹配逻辑(如关键词匹配权重)计算得分
- 自定义技能可调用Azure Cognitive Search的搜索API,针对单个SKU的字段执行搜索,获取得分后写入
- 在产品结果中,将SKU数组按
relevanceScore降序排列,同时保留所有非相关SKU
- 过滤与分面:
- 针对SKU的过滤和分面,可通过Azure Cognitive Search的
$filter和$facet对嵌套字段操作(如$filter=skus/any(s: s/color eq 'Red'))
- 针对SKU的过滤和分面,可通过Azure Cognitive Search的
优势:
- 保留原有的产品文档结构,无需大量重构索引
- 非相关SKU天然保留在产品文档中
劣势:
- 相关性得分计算需要额外的自定义逻辑,精准度可能不如原生搜索得分
- 自定义技能会增加搜索延迟,客户端计算则会增加前端负载
- 分面和过滤的灵活性略逊于扁平化索引
方案3:双索引优化(改进现有临时方案)
如果团队已经采用双索引(产品索引+SKU索引),可做以下优化:
核心优化点:
- 索引关联:
- 产品索引和SKU索引通过
productId严格关联,SKU索引中保留完整的产品字段副本(或仅保留productId和产品核心字段)
- 产品索引和SKU索引通过
- 搜索流程优化:
- 第一步:搜索SKU索引,获取匹配的SKU列表及相关性得分,按
productId分组,保留每个产品下得分最高的SKU作为"主打SKU" - 第二步:通过
productId从产品索引获取完整的产品信息,同时关联该产品下的所有SKU(从SKU索引查询) - 第三步:在产品结果中,将SKU按相关性得分排序,合并非相关SKU
- 第一步:搜索SKU索引,获取匹配的SKU列表及相关性得分,按
- 分页处理:
- 分页基于产品维度,通过SKU索引分组后的
productId列表进行$top和$skip,避免重复获取产品数据
- 分页基于产品维度,通过SKU索引分组后的
优势:
- 复用现有双索引结构,减少重构成本
- 兼顾产品和SKU的独立查询能力
劣势:
- 需要两次查询(SKU索引+产品索引),增加搜索延迟
- 数据一致性需要额外维护(如产品或SKU更新时需同步两个索引)
内容的提问来源于stack exchange,提问作者Kurt S
相关产品推荐
相关产品推荐

