如何使用mongodb中两个集合的聚合计算利润?
我有两个系列,订单和产品类型 产品类型:如何使用mongodb中两个集合的聚合计算利润?,mongodb,aggregation-framework,Mongodb,Aggregation Framework,我有两个系列,订单和产品类型 产品类型: { "_id" : 609d79de5909592f2635c64e, "name" : "T-Shirt", "subType" : "Round Neck", "__v" : 0, "size" : "XXL", "sell
{
"_id" : 609d79de5909592f2635c64e,
"name" : "T-Shirt",
"subType" : "Round Neck",
"__v" : 0,
"size" : "XXL",
"sellingPrice" : 320,
"createdAt" : ISODate("2021-05-18T05:22:00.695+0000"),
"actualPrice" : 200,
"updatedAt" : ISODate("2021-05-25T12:11:50.986+0000")
},
{
"_id" : 609d79de5909592f2635c64d,
"name" : "T-Shirt",
"subType" : "V Neck",
"__v" : 0,
"size" : "XXL",
"sellingPrice" : 290,
"createdAt" : ISODate("2021-05-18T05:22:00.695+0000"),
"actualPrice" : 200,
"updatedAt" : ISODate("2021-05-25T12:11:50.986+0000")
}
订单:
{
"_id" : "60a63e369cf3a806c0209bd8",
"items" : [
{
"type" : "609d79de5909592f2635c64e",
"quantity" : 1,
"sellingPrice" : 320
},
{
"type" : "609d79de5909592f2635c64d",
"quantity" : 2,
"sellingPrice" : 290
}
],
"orderId" : "ORD101",
"from" : "Abc",
"to" : "xyz",
"createdAt" : ISODate("2021-05-20T10:47:18.920+0000"),
"__v" : 0,
"tracking" : "12345678"
}
我想计算每个订单的总利润,如下所示:
{orderId: "ORD101", createdAt: ISODate("2021-05-18T05:22:00.695+0000"), profit: 300}
我不知道如何加入这两个集合来计算利润
但我在node中尝试了如下操作:
Order.aggregate([{
$unwind: '$items'
}, {
$project: {
orderId:1,
quantity: "$items.quantity",
sellingPrice: {
$multiply: [
{"$ifNull": ["$items.quantity", 0]},
{"$ifNull": ["$items.price", 0]}
]
},
type: '$items.type'
}
}])
.exec(function(err, transactions) {
//console.log(transactions);
ProductType.populate(transactions,{path: 'type', select: 'actualPrice' }, function(err, populatedTransactions) {
//res.json(populatedTransactions);
var items = [];
var totalProfit = 0;
if(populatedTransactions){
populatedTransactions.forEach( order => {
if( order.quantity != undefined && order.sellingPrice != undefined && order.sellingPrice > 0){
let profit = order.sellingPrice - (order.quantity * order.type.actualPrice);
totalProfit = totalProfit + profit;
items.push({ orderId: order.orderId, profit: profit });
}
})
res.status(200).json({data: items, totalProfit: totalProfit});
}
});
});
这条路对吗
这里我在数组中使用$unwind
,然后填充producttypes集合以获得实际价格,然后进行计算以获得利润。
显示必填字段$project
解构$unwind
数组项
与$lookup
集合productTypes
- 计算利润
从项目$arrayElemAt
结果中获取第一个元素实际价格
$subtract
bysellingPrice
actualPrice
以上结果与$multiply
数量
按订单$group
并获取所需字段和金额\u id
利润
感谢您的快速回复和解决方案。但问题是在游戏环境中,它工作正常,但在我的系统中$lookup的“item”是空数组,这是我的mongo版本的问题吗?以下是我的mongo版本详细信息MongoDB shell版本4.4.5构建信息:{“版本”:“4.4.5”,“gitVersion”:“ff5cb77101b052fa02da43b8538093486cf9b3f7”,“模块”:[],“分配器”:“系统”,“环境”:{“distarch”:“x86_64”,“目标_arch”:“x86_64”}不,这不是mongo版本问题,您能否确认订单中的
项。type
字段是字符串类型还是对象id类型?它是objectId“items”:[{“type”:objectId(“609D79DE590952F2635C64D”),“quantity”:numberprint(0),“price”:numberprint(0)}]好的,如果它是objectid,我看不出有任何问题。非常感谢@turivishal,错误来自我这边,我重命名了一个字段,现在它给出了正确的结果。非常感谢您的快速解决方案。
Order.aggregate([
{
$project: {
orderId: 1,
createdAt: 1,
items: 1
}
},
{ $unwind: "$items" },
{
$lookup: {
from: "productTypes", // replace your actual collection name
localField: "items.type",
foreignField: "_id",
as: "item"
}
},
{
$addFields: {
profit: {
$multiply: [
{
$subtract: [
"$items.sellingPrice",
{ $arrayElemAt: ["$item.actualPrice", 0] }
]
},
"$items.quantity"
]
}
}
},
{
$group: {
_id: "$_id",
orderId: { $first: "$orderId" },
createdAt: { $first: "$createdAt" },
profit: { $sum: "$profit" }
}
}
])