MongoDB聚合按订单分组,实现产品hasDefect字段规则汇总
MongoDB聚合实现:按订单汇总产品缺陷状态
需求说明
现有MongoDB集合数据,需通过聚合框架按order_id分组,并依据以下规则汇总订单级别下各产品的hasDefect字段:
- 同一订单内,同款产品所有订单项的
hasDefect均为"YES"时,订单级别该产品的hasDefect设为"YES"; - 若同款产品的
hasDefect同时存在"YES"、"NO"、"NOT_SURE"三种值,订单级别该产品的hasDefect设为"NO"; - 若同款产品的
hasDefect仅混合"YES"和"NOT_SURE",订单级别该产品的hasDefect设为"NOT_SURE"。
集合数据示例
[ { "order_line_item_id": 1, "order_id": 100, "products": [ {"name": "Shoe","hasDefect": "YES"}, {"name": "Pant","hasDefect": "NO"}, {"name": "Shirt","hasDefect": "NOT_SURE"} ] }, { "order_line_item_id": 2, "order_id": 100, "products": [ {"name": "Shoe","hasDefect": "YES"}, {"name": "Pant","hasDefect": "YES"}, {"name": "Shirt","hasDefect": "YES"} ] }, { "order_line_item_id": 3, "order_id": 101, "products": [ {"name": "Shoe","hasDefect": "YES"}, {"name": "Pant","hasDefect": "NO"}, {"name": "Shirt","hasDefect": "NOT_SURE"} ] } ]
预期输出(以order_id=100为例)
[ { "order_id": 100, "products": [ {"name": "Shoe","hasDefect": "YES"}, {"name": "Pant","hasDefect": "NO"}, {"name": "Shirt","hasDefect": "NOT_SURE"} ] } ]
聚合管道解决方案
db.collection.aggregate([ // 拆分每个订单项中的products数组,让每个产品单独成为一条文档 { $unwind: "$products" }, // 按订单ID和产品名称分组,收集该产品所有不重复的hasDefect值 { $group: { _id: { order_id: "$order_id", product_name: "$products.name" }, defect_values: { $addToSet: "$products.hasDefect" } } }, // 根据规则判断订单级别产品的hasDefect值 { $addFields: { hasDefect: { $cond: [ // 规则1:所有值都是YES(集合长度为1且包含YES) { $and: [ { $eq: [ { $size: "$defect_values" }, 1 ] }, { $in: [ "YES", "$defect_values" ] } ] }, "YES", { $cond: [ // 规则2:同时包含三种值 { $and: [ { $in: [ "YES", "$defect_values" ] }, { $in: [ "NO", "$defect_values" ] }, { $in: [ "NOT_SURE", "$defect_values" ] } ] }, "NO", // 规则3:仅混合YES和NOT_SURE "NOT_SURE" ] } ] } } }, // 重新按订单ID分组,整理products数组 { $group: { _id: "$_id.order_id", products: { $push: { name: "$_id.product_name", hasDefect: "$hasDefect" } } } }, // 调整输出字段格式,移除默认_id { $project: { _id: 0, order_id: "$_id", products: 1 } } ])
代码说明
- $unwind:拆分订单项的
products数组,让每个产品成为独立文档,便于后续按产品维度处理。 - 第一个$group:按订单ID和产品名称分组,用
$addToSet收集该产品所有不重复的缺陷状态,避免重复值干扰规则判断。 - $addFields:通过嵌套
$cond依次匹配三条规则,计算出订单级别产品的最终缺陷状态。 - 第二个$group:重新按订单ID聚合,将同一订单下的产品信息合并为
products数组。 - $project:调整输出字段,移除系统生成的
_id,将分组ID重命名为order_id,匹配预期输出格式。
内容的提问来源于stack exchange,提问作者Fadd
相关产品推荐
相关产品推荐

