MongoDB关联数组元素聚合查询并计算总价的问题
MongoDB聚合查询:关联集合并计算物料总价
我有两个互相关联的MongoDB集合:semiproducts和materials。semiproducts集合中mater数组的id字段与materials集合的_id字段关联。我需要通过聚合查询关联获取对应物料信息,并为semiproducts文档添加totalPrice字段,该字段为关联物料的总价之和。我尝试了一段聚合查询语句,但未得到预期结果,寻求正确实现方案。
集合结构
semiproducts集合
semiproducts = [ { _id: "64afad9eda7e337a51b304c8", name: "Cream", description: "One Degree", mater: [ { mtNumber: 1000, id: "64afa9dcda7e337a51b30467", }, { mtNumber: 150, id: "64afaa08da7e337a51b3046d", }, { mtNumber: 250, id: "64afa9a4da7e337a51b3045e", }, ], }, ];
materials集合
materials = [ { _id: "64afaa08da7e337a51b3046d", name: "Un", type: "Gıda", amount: 1000, price: 13.5, description: "21", date: "2023-07-05T00:00:00.000Z", }, { _id: "64afa9a4da7e337a51b3045e", name: "Toz Şeker", type: "Gıda", amount: 1000, price: 22, date: "2023-07-13T00:00:00.000Z", }, { _id: "64afa9dcda7e337a51b30467", name: "Tereyağ", type: "Gıda", amount: 1000, price: 170, date: "2023-07-13T00:00:00.000Z", }, ];
预期结果
semiproducts = [ { _id: "64afad9eda7e337a51b304c8", name: "Cream", description: "One Degree", mater: [ { mtNumber: 1000, id: "64afa9dcda7e337a51b30467", }, { mtNumber: 150, id: "64afaa08da7e337a51b3046d", }, { mtNumber: 250, id: "64afa9a4da7e337a51b3045e", }, ], totalPrice: 1253 // 关联物料的总价之和 }, ];
尝试的聚合查询语句
[ { $lookup: { from: "materials", let: { mat_id: "$mater.id" }, pipeline: [ { $match: { $expr: { $in: ["$_id", "$$mat_id"], }, }, }, ], as: "mat_info", }, }, { $addFields: { total: { $sum: "$mat_info.price" }, }, }, ];
问题分析与正确方案
你的查询仅直接求和物料的price字段,但未结合semiproducts中mater数组的mtNumber(使用数量)进行计算。要得到正确的totalPrice,需要将每个mater元素与对应物料的price关联,计算单种物料的总价后再求和。
以下是正确的聚合查询:
db.semiproducts.aggregate([ // 关联materials集合,获取所有关联物料信息 { $lookup: { from: "materials", localField: "mater.id", foreignField: "_id", as: "mat_info" } }, // 计算totalPrice:遍历mater数组,匹配对应物料价格并计算总价后求和 { $addFields: { totalPrice: { $sum: { $map: { input: "$mater", as: "item", in: { // 示例按「使用数量 × 单位价格」计算,单位价格 = price/amount $multiply: [ "$$item.mtNumber", { $divide: [ { $getField: { field: "price", input: { $first: { $filter: { input: "$mat_info", cond: { $eq: ["$$this._id", "$$item.id"] } } } } } }, { $getField: { field: "amount", input: { $first: { $filter: { input: "$mat_info", cond: { $eq: ["$$this._id", "$$item.id"] } } } } } } ] } ] } } } } } }, // 可选:移除临时的mat_info字段,保持文档简洁 { $project: { mat_info: 0 } } ])
说明
- $lookup关联:使用
localField和foreignField直接关联两个集合的字段,获取所有关联物料到mat_info数组。 - 总价计算逻辑:
- 用
$map遍历mater数组的每个元素; - 用
$filter从mat_info中匹配当前元素对应的物料; - 根据业务需求计算单种物料的总价(示例中是
mtNumber乘以单位价格,即price/amount); - 用
$sum将所有单物料总价求和得到totalPrice。
- 用
- 若你的业务中
price就是mtNumber对应的单位价格,无需按amount换算,可将$multiply部分简化为:$multiply: [ "$$item.mtNumber", { $getField: { field: "price", input: { $first: { $filter: { input: "$mat_info", cond: { $eq: ["$$this._id", "$$item.id"] } } } } } } ]
内容的提问来源于stack exchange,提问作者Mehmet Altan
相关产品推荐
相关产品推荐

