我们说我们有以下文件:
{ type: "hourly", amount: 100 },
{ type: "flat", amount: 350 },
{ type: "hourly", amount: 200 },
{ type: "payment", amount: 100 },
{ type: "payment", amount: 200 }
在管道中的某个地方,我想为每个"类型积累总计。" 除了所有个人记录之外,我想知道我们的总计如下:
hourly: $300
flat: $350
payment: $300
我查看了 $ add 和 $ sum ,这些似乎对添加给定记录的字段非常有用,而不是累积总计。
到目前为止,我的聚合过滤了我想要的所有记录,并且不使用任何分组。我不想将记录分组。我需要个人记录以及总计。
我认为 $ push 命令可能是相关的,如果我必须 $ group - 可能是 $ push - 将个人记录转换为一个数组,使其与所有其余记录一起退出。请在此处查看答案:Using Mongo aggregation to calculate sum of values
在我的情况下,我有一个聚合,没有收集任何总数,如下所示。对于每个返回的文档,都有一个"类型"字段(例如,"每小时","平,""付款")。
myAggregate = [
{ $sort: { date: -1 } },
{
$match: query
},
{
$lookup: {
from: "contacts", // collection name in db
localField: "billerId",
foreignField: "_id",
as: "biller"
}
},
{
$unwind: "$biller"
},
{
$lookup: {
from: "matters", // collection name in db
localField: "matterId",
foreignField: "_id",
as: "matter"
}
},
{
$unwind: "$matter"
},
{
$lookup: {
from: "contacts", // collection name in db
localField: "matter.clientId",
foreignField: "_id",
as: "client"
}
},
{
$unwind: "$client"
},
];
" myAggregate"看起来是为了积累总计并返回所有个人(未分组)记录?
经过深思熟虑:如果对我来说同样有效的话,那就是"手动"遍历记录以获得总计,我可以做到这一点。我认为MongoDb必须更有效率,因为他们不愿意制作这些功能。
编辑1:
以下是" myAggregate"根据Veeram的建议附加:
// Do we need to get only records which match the matter's contactId?
if (query2 != "") {
myAggregate.push( { $match: query2 } );
}
// Get grand totals.
myAggregate.push({ "$group": { "_id": "$transactionType",
"documents": { "$push": "$$ROOT" },
"grandtotal": {"$sum":"$amount"}
}
});
答案 0 :(得分:1)
在Veeram的帮助下,我通过在他建议的project
阶段之前添加group
阶段来获得总数。我还将group
的_id设置为 null (根据Mongo documentation),以避免将我的所有文档分成组。
$project: {
_id: 1,
firmId: 1,
... plus, a bunch more fields.
// Project some fields to allow totaling by transactionType.
hourlyAmount: { $cond: { if: { $eq: ["$transactionType", "hourly"] }, then: "$amount", else: 0 } },
flatAmount: { $cond: { if: { $eq: ["$transactionType", "flat"] }, then: "$amount", else: 0 } },
paymentAmount: { $cond: { if: { $eq: ["$transactionType", "payment"] }, then: "$amount", else: 0 } },
expenseAmount: { $cond: { if: { $eq: ["$transactionType", "expense"] }, then: "$amount", else: 0 } },
creditAmount: { $cond: { if: { $eq: ["$transactionType", "credit"] }, then: "$amount", else: 0 } },
debitAmount: { $cond: { if: { $eq: ["$transactionType", "debit"] }, then: "$amount", else: 0 } }
}
然后,根据Veeram,我分组如下:
myAggregate.push({
"$group": {
"_id": null, //"$transactionType",
"documents": { "$push": "$$ROOT" },
"hourlyTotal": {"$sum": "$hourlyAmount"},
"flatTotal" : {"$sum": "$flatAmount"},
"paymentTotal" : {"$sum": "$paymentAmount"},
"expenseTotal" : {"$sum": "$expenseAmount"},
"creditTotal" : {"$sum": "$creditAmount"},
"debitTotal" : {"$sum": "$debitAmount"},
}
});
它工作得很漂亮,一切都以一个元素的形式返回。请注意,“documents”是数组元素的属性,因此它们可以由<arrayElements>[0]
。文档引用。我的所有个人总数都在那里(例如,arrayElements>[0].hourlyTotal
)。