MongoDB多字段关联两个集合并计算购物车总价
MongoDB多集合关联计算购物车项价格及总价实现方案
需求说明
关联shopping_cart和product两个集合,通过product_id与option_id(对应product集合的options_id)匹配,计算每个购物车项的价格(quantity × 对应产品选项的selling_price),同时支持统计购物车的总价。
集合数据示例
shopping_cart集合
{ "_id" : ObjectId("62f4dfe964cb83eae07634f4"), "user" : ObjectId("62e4ef9aa7bae2d09973f9a0"), "shopping_cart_items" : [ { "product_id" : ObjectId("62f38262a223a7e04f95f459"), "option_id" : ObjectId("62f382eea223a7e04f95f45a"), "quantity" : NumberInt(3) }, { "product_id" : ObjectId("62f38262a223a7e04f95f459"), "option_id" : ObjectId("62f382eea223a7e04f95f45b"), "quantity" : NumberInt(1) } ] }
product集合
{ "_id" : ObjectId("62f38262a223a7e04f95f459"), "product_options" : [ { "options_id" : ObjectId("62f382eea223a7e04f95f45a"), "selling_price" : NumberInt(1500) }, { "options_id" : ObjectId("62f382eea223a7e04f95f45b"), "selling_price" : NumberInt(2250) }, { "options_id" : ObjectId("62f382eea223a7e04f95f45c"), "selling_price" : NumberInt(3000) } ] }
实现方案
1. 生成单个购物车项带价格的输出(匹配期望格式)
使用MongoDB聚合框架执行以下查询:
db.shopping_cart.aggregate([ // 拆分购物车项数组为独立文档 { $unwind: "$shopping_cart_items" }, // 关联product集合,匹配product_id { $lookup: { from: "product", localField: "shopping_cart_items.product_id", foreignField: "_id", as: "product_info" } }, // 展开关联的product数据数组 { $unwind: "$product_info" }, // 展开产品选项数组,方便匹配option_id { $unwind: "$product_info.product_options" }, // 精准匹配购物车项与对应产品选项 { $match: { $expr: { $eq: ["$shopping_cart_items.option_id", "$product_info.product_options.options_id"] } } }, // 计算单个项价格并重组输出结构 { $project: { _id: 1, user: 1, shopping_cart_items: { product_id: "$shopping_cart_items.product_id", option_id: "$shopping_cart_items.option_id", quantity: "$shopping_cart_items.quantity", price: { $multiply: ["$shopping_cart_items.quantity", "$product_info.product_options.selling_price"] } } } } ])
执行后会输出与期望一致的单个购物车项文档,每个文档包含计算后的price字段。
2. 统计购物车总价(保留明细+总价)
若需要同时获取购物车项明细和总价,使用以下聚合查询:
db.shopping_cart.aggregate([ { $unwind: "$shopping_cart_items" }, { $lookup: { from: "product", localField: "shopping_cart_items.product_id", foreignField: "_id", as: "product_info" } }, { $unwind: "$product_info" }, { $unwind: "$product_info.product_options" }, { $match: { $expr: { $eq: ["$shopping_cart_items.option_id", "$product_info.product_options.options_id"] } } }, // 为购物车项添加价格字段 { $addFields: { "shopping_cart_items.price": { $multiply: ["$shopping_cart_items.quantity", "$product_info.product_options.selling_price"] } } }, // 按购物车ID分组,汇总明细与总价 { $group: { _id: "$_id", user: { $first: "$user" }, shopping_cart_items: { $push: "$shopping_cart_items" }, total_price: { $sum: "$shopping_cart_items.price" } } } ])
该查询会输出每个购物车的完整信息,包含所有带价格的购物车项,以及计算得到的total_price(购物车总价)。
关键阶段说明
$unwind:将数组字段拆分为单个文档,便于后续关联和匹配操作。$lookup:实现集合间关联,功能类似SQL的JOIN。$match:精准匹配购物车项对应的产品选项,确保价格计算准确。$multiply:执行乘法运算,计算单个购物车项的价格。$group:按购物车ID聚合,重组明细数据并计算总价。
内容的提问来源于stack exchange,提问作者pn1982
相关产品推荐
相关产品推荐

