如何通过MongoDB聚合获取搜索结果中去重的产品主副类别
解决方案
你可以通过MongoDB聚合管道实现需求,以下是具体的聚合查询,能返回去重后的主、子类别层级结构:
db.products.aggregate([ // 1. 匹配全文搜索结果(不设limit,确保覆盖所有相关产品) { $match: { $text: { $search: 'IPhone 6' } } }, // 2. 按主类别分组,收集唯一的子类别组合 { $group: { _id: { main_category_id: "$main_category_id", main_category_name: "$main_category_name" }, sub_category_entries: { $addToSet: { sub1_name: "$sub_category_1_name", sub1_id: "$sub_category_1_id", sub2_name: "$sub_category_2_name", sub2_id: "$sub_category_2_id", sub3_name: "$sub_category_3_name", sub3_id: "$sub_category_3_id" } } } }, // 3. 整理子类别为层级嵌套结构 { $addFields: { sub_categories: { $map: { input: { // 按一级子类别去重,合并二级子类别 $reduce: { input: "$sub_category_entries", initialValue: [], in: { $let: { vars: { exists: { $filter: { input: "$$value", cond: { $and: [ { $eq: ["$$this.sub1_id", "$$current.sub1_id"] }, { $eq: ["$$this.sub1_name", "$$current.sub1_name"] } ] } } } }, in: { $cond: { if: { $ne: [{ $size: "$$exists" }, 0] }, then: { $map: { input: "$$value", as: "item", in: { $cond: { if: { $and: [ { $eq: ["$$item.sub1_id", "$$current.sub1_id"] }, { $eq: ["$$item.sub1_name", "$$current.sub1_name"] } ] }, then: { $mergeObjects: [ "$$item", { sub2_list: { $addToSet: { sub2_name: "$$current.sub2_name", sub2_id: "$$current.sub2_id", sub3_list: [{ sub3_name: "$$current.sub3_name", sub3_id: "$$current.sub3_id" }].filter(x => x.sub3_name) } } } ] }, else: "$$item" } } } }, else: { $concatArrays: [ "$$value", [{ sub1_name: "$$current.sub1_name", sub1_id: "$$current.sub1_id", sub2_list: [{ sub2_name: "$$current.sub2_name", sub2_id: "$$current.sub2_id", sub3_list: [{ sub3_name: "$$current.sub3_name", sub3_id: "$$current.sub3_id" }].filter(x => x.sub3_name) }].filter(x => x.sub2_name) }] ] } } } } } } }, as: "sub1", in: { sub_category_name_1: "$$sub1.sub1_name", sub_category_id_1: "$$sub1.sub1_id", sub_category_name_2: { $map: { input: "$$sub1.sub2_list", as: "sub2", in: { sub_category_name_2: "$$sub2.sub2_name", sub_category_id_2: "$$sub2.sub2_id", sub_category_name_3: "$$sub2.sub3_list" } } } } } } } }, // 4. 调整输出格式为期望结构 { $project: { _id: 0, main_category_name: "$_id.main_category_name", main_category_id: "$_id.main_category_id", sub_categories: 1 } }, // 可选:按主类别名称排序 { $sort: { main_category_name: 1 } } ])
关键说明:
- 替换字段名:如果你的产品集合中子类别字段名不是
sub_category_1_name、sub_category_1_id这类,需要将查询中对应的sub1_name、sub1_id等替换为实际字段名。 - 空值处理:通过
filter过滤掉未定义或空的子类别,确保空层级显示为数组。 - 去重逻辑:使用
$addToSet和$reduce实现各级子类别去重,避免重复条目。
内容的提问来源于stack exchange,提问作者Denys Medvediev
相关产品推荐
相关产品推荐

