MongoDB嵌套集合聚合问题:门店交易商品统计
正确MongoDB聚合方案
问题背景
online_orders集合中,items字段为JSON字符串格式,需按门店分组统计商品总金额,且销售数量固定返回0。
示例集合数据
// online_orders集合文档示例 [ { "store_id": "S001", "store_name": "北京朝阳店", "items": "[{\"product_id\":\"P001\",\"product_name\":\"矿泉水\",\"price\":2,\"quantity\":3},{\"product_id\":\"P002\",\"product_name\":\"面包\",\"price\":5,\"quantity\":2}]", "order_time": ISODate("2024-05-01T10:30:00Z") }, { "store_id": "S001", "store_name": "北京朝阳店", "items": "[{\"product_id\":\"P001\",\"product_name\":\"矿泉水\",\"price\":2,\"quantity\":5}]", "order_time": ISODate("2024-05-02T14:15:00Z") }, { "store_id": "S002", "store_name": "上海浦东店", "items": "[{\"product_id\":\"P003\",\"product_name\":\"牛奶\",\"price\":6,\"quantity\":4}]", "order_time": ISODate("2024-05-01T09:20:00Z") } ]
常见无效方案(供对比)
直接对字符串类型的items执行$unwind会失败,因为$unwind仅支持数组:
// 无效代码 db.online_orders.aggregate([ { $unwind: "$items" }, // 报错:Field path must be an array but is string { $group: { _id: "$store_id", total_amount: { $sum: { $multiply: ["$items.price", "$items.quantity"] } }, sales_quantity: { $sum: "$items.quantity" } } } ])
正确聚合管道
核心步骤:解析JSON字符串为数组 → 展开数组 → 计算单商品金额 → 按门店分组统计,同时固定销售数量为0:
db.online_orders.aggregate([ // 1. 将items的JSON字符串解析为数组 { $addFields: { parsed_items: { $jsonParse: "$items" } } }, // 2. 展开商品数组,将每个商品转为独立文档 { $unwind: "$parsed_items" }, // 3. 计算单商品的交易金额(单价*数量) { $addFields: { item_amount: { $multiply: ["$parsed_items.price", "$parsed_items.quantity"] } } }, // 4. 按门店分组,统计总金额,销售数量固定返回0 { $group: { _id: { store_id: "$store_id", store_name: "$store_name" }, total_amount: { $sum: "$item_amount" }, sales_quantity: { $sum: 0 } // 固定返回0 } }, // 5. 格式化输出字段(可选,让结构更清晰) { $project: { _id: 0, store_id: "$_id.store_id", store_name: "$_id.store_name", total_amount: 1, sales_quantity: 1 } } ])
预期输出格式
[ { "store_id": "S001", "store_name": "北京朝阳店", "total_amount": 31, "sales_quantity": 0 }, { "store_id": "S002", "store_name": "上海浦东店", "total_amount": 24, "sales_quantity": 0 } ]
关键说明
$jsonParse:MongoDB 4.4+支持的运算符,用于将JSON字符串解析为BSON对象/数组,是处理该场景的核心。$unwind:仅能处理数组类型字段,必须先解析字符串再展开。- 固定销售数量为0:通过
$group中$sum: 0实现,确保每个分组的该字段值恒为0。
内容的提问来源于stack exchange,提问作者jarvis
相关产品推荐
相关产品推荐

