mongodb - 如何使用 mongodb 中两个集合的聚合计算利润?
问题描述
我有两个集合,订单和产品类型
产品类型:
{
"_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}
我不知道如何加入这两个集合来计算利润。
但是我在节点中尝试了类似下面的东西:
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
解构items
数组$lookup
带productTypes
收藏- 计算利润
$arrayElemAt
从项目actualPrice
结果中获取第一个元素$subtract
sellingPrice
经过actualPrice
$multiply
以上结果与quantity
$group
按订单_id
并获取必填字段和总和profit
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" }
}
}
])
推荐阅读
- javascript - 如何优化移动网络应用程序(ext js 现代)
- postgresql - Postgresql ldap 身份验证
- java - 在java中生成范围
- r - 从 csv 文件批量重命名文件 r
- python - 使用 Python 而不是 shell 脚本循环减速
- python - 根据 pandas df 中的列对行进行分组(仅填充布尔值)
- python - Python 记录器不适用于子进程
- sas - SAS 数据格式转 int 格式
- androidimageslider - 如何使用 Viewpager 添加幻灯片图像
- javascript - 我如何在反应中包含第三方库(turn.js)