我有一个交易模型,其中我有交易的描述和状态字段。如下所示
[
{
"_id": "5795e3f4f4a0fb8c1dff20ad",
"description": "This is a transcation",
"invoice_id": "5795db00bfa9d366194a454d",
"amount": 50
},
{
"_id": "5795e3faf4a0fb8c1dff20ae",
"description": "This is a transcation",
"invoice_id": "5795db00bfa9d366194a454d",
"amount": 100
}
]
我正在使用聚合和分组这些记录来查找匹配对象的totalAmount
。所以为此我正在使用这个查询:
Transaction.aggregate([{
$match: {
invoice: ObjectId("5795db00bfa9d366194a454d")
}
}, {
$group: {
_id: {
_id: "$_id"
},
count: {
$sum: 1
},
totalAmount: {
$sum: "$amount"
},
}
}
])
当我运行时,我得到以下结果
/* 1 */
{
"_id": {
"_id": ObjectId("5796031e07bad1d21f3af823")
},
"count": 1.0,
"totalAmount": 100
}
/* 2 */
{
"_id": {
"_id": ObjectId("5795e3f4f4a0fb8c1dff20ad")
},
"count": 1.0,
"totalAmount": 50
}
但我希望获得具有特定invoice_id
和totalAMount
以及description
等其他字段的所有匹配对象。应该是这样的事情
[{
"_id": {
"_id": ObjectId("5795e3f4f4a0fb8c1dff20ad")
},
"description": "description of first object",
"count": 5.0,
"totalAmount": 350
}, {
"_id": {
"_id": ObjectId("5795e3f4f4a0fb8c1dff20ad")
},
"description": "description of second object",
"count": 5.0,
"totalAmount": 350
}]
如何实现此解决方案?
答案 0 :(得分:4)
经过几次澄清(如果你真的感兴趣,请检查this code)我写了下一个查询。
db.invoices.aggregate([{
$match: {
"invoice_id": ObjectId("5795db00bfa9d366194a454d")
}
}, {
$group: {
_id: {
_id: "$invoice_id"
},
count: {
$sum: 1
},
info: {
$push: {
id: "$_id",
amount: "$amount",
description: "$description"
}
},
totalAmount: {
$sum: "$amount"
}
}
}, {
$unwind: "$info"
}, {
$project: {
_id: "$info.id",
count: "$count",
invoice_id: "$_id",
totalAmount: "$totalAmount",
amount: "$info.amount",
description: "$info.description"
}
}])
这里发生了什么?
我们按此ID对其进行分组以计算totalAmount
,但同时将所有其他信息推送到info
字段。之后我们有单个文档,如下所示:
{
"_id" : {
"_id" : "5795db00bfa9d366194a454d"
},
"count" : 2,
"info" : [
{
"id" : ObjectId("5795e3f4f4a0fb8c1dff20ad"),
"amount" : 50,
"description" : "This is a transcation"
},
{
"id" : ObjectId("5796031e07bad1d21f3af823"),
"amount" : 100,
"description" : "FSC evening class"
}
],
"totalAmount" : 150
}
我们在此文档上执行$unwind
,创建了两个具有下一个结构的文档
{
"_id" : {
"_id" : "5795db00bfa9d366194a454d"
},
"count" : 2,
"info" : {
"id" : ObjectId("5795e3f4f4a0fb8c1dff20ad"),
"amount" : 50,
"description" : "This is a transcation"
},
"totalAmount" : 150
}
最后一部分是将我们的结构投射到所需的结构。这很简单,无需另外解释。
现在您将能够以这种形式获得结果:
/* 1 */
{
"_id" : ObjectId("5795e3f4f4a0fb8c1dff20ad"),
"count" : 2.0,
"totalAmount" : 150,
"invoice_id" : {
"_id" : ObjectId("5795db00bfa9d366194a454d")
},
"amount" : 50,
"description" : "This is a transcation"
}
/* 2 */
{
"_id" : ObjectId("5796031e07bad1d21f3af823"),
"count" : 2.0,
"totalAmount" : 150,
"invoice_id" : {
"_id" : ObjectId("5795db00bfa9d366194a454d")
},
"amount" : 100,
"description" : "FSC evening class"
}
答案 1 :(得分:0)
在代码中更改group by的顺序: -
db.invoices.aggregate([{ $match: { "invoice_id": `ObjectId("5795db00bfa9d366194a454d")` } }, { $group: { _id: { _id: "$invoice_id" }, description: { $first: "$description" } count: { $sum: 1 }, totalAmount: { $sum: "$amount" } } }])