如何在MongoDB中结合Group By与Lookup实现多过滤聚合查询
MongoDB聚合:结合$group与$lookup实现目标结果
以下是针对你的需求的正确聚合查询,同时会指出你原有代码的问题:
正确聚合管道
db.filter_weights.aggregate([ // 筛选目标分类(替换成你需要的category,示例为laptops) { $match: { category: "laptops" } }, // 关联filter_options_weights集合,同时匹配filter_id和category避免跨分类关联 { $lookup: { from: "filter_options_weights", let: { filterId: "$filter_id", cat: "$category" }, pipeline: [ { $match: { $expr: { $and: [ { $eq: ["$filter_id", "$$filterId"] }, { $eq: ["$category", "$$cat"] } ] } } }, // 提前整理选项的键值对格式 { $project: { _id: 0, option: { $arrayToObject: [[{ k: "$filter_option_value", v: "$counter" }]] } } } ], as: "filter_option_value" } }, // 提取整理好的选项数组,调整输出结构 { $project: { _id: 0, category: 1, counter: 1, filter_id: 1, filter_option_value: { $map: { input: "$filter_option_value", as: "item", in: "$$item.option" } } } } ])
原有代码的问题分析
- 集合名称错误:
$lookup的from参数写为filter_values_weights,实际目标集合是filter_options_weights - 关联条件不严谨:仅通过
filter_id关联可能匹配到其他分类下的同ID选项,需要同时匹配category - $group阶段冗余:你的需求中
filter_weights的counter已经是对应filter的总和,不需要额外分组求和,且原$group会丢失category等关键字段 - 字段覆盖问题:
$lookup的as参数使用了filter_id,会直接覆盖原集合的filter_id字段
最终输出结果
执行上述查询后,会得到你期望的结构:
{ "category": "laptops", "counter": 7, "filter_id": "brands", "filter_option_value": [ { "Dell": 2 }, { "Apple": 5 } ] }
内容的提问来源于stack exchange,提问作者Madiar Turgenbaev
相关产品推荐
相关产品推荐

