Reputation: 2291
I am using mongodb and trying to construct a groupby query. A single document looks something like this
{
"_id" : "ca5ff110697611e89c2d9a0012d6e110",
"CreatedAt" : ISODate("2018-06-06T16:15:55.000Z,
"CreatedBy" : {
"Email" : "[email protected]",
"Name" : "Neo",
"_id" : "User001"
},
},
"Salary" : 200000
"Branch" : "C2"
}
and my groupby query looks something like this
[{'$project': {'Branch': 1, 'CreatedAt.year':{$year:"$CreatedAt"}, 'CreatedBy': 1, 'Salary': 1}},
{'$group': {'_id': {'Branch': '$Branch',
'Salary': '$Salary',
'CreatedAt.year': "$CreatedAt.year" ,
'CreatedBy': '$CreatedBy._id'},
'Salary': {'$sum': '$Salary'},
'CreatedBy': "$CreatedBy"
}},
]
As you see the CreatedBy
is a nested field and grouping on its _id
field results in just _id
field but I want to preserve the name
and email
while grouping. Grouping by the whole CreatedBy
because the user may change their name at some point and the old documents will have old name.
Upvotes: 0
Views: 42
Reputation: 9295
The $group
stage needs an accumulator operator for each field. To keep the CreatedBy
field, you can use $first
for example:
the new query:
db.collection.aggregate([
{
"$project": {
"Branch": 1,
"CreatedAt.year": {
$year: "$CreatedAt"
},
"CreatedBy": 1,
"Salary": 1
}
},
{
"$group": {
"_id": {
"Branch": "$Branch",
"Salary": "$Salary",
"CreatedAtYear": "$CreatedAt.year",
"CreatedBy": "$CreatedBy._id"
},
"Salary": {
"$sum": "$Salary"
},
"CreatedBy": {
"$first": "$CreatedBy"
}
}
}
])
result:
[
{
"CreatedBy": {
"Email": "[email protected]",
"Name": "Neo",
"_id": "User001"
},
"Salary": 200000,
"_id": {
"Branch": "C2",
"CreatedAtYear": 2018,
"CreatedBy": "User001",
"Salary": 200000
}
}
]
you can try it online here: mongoplayground.net/p/cVNHRD5Rv21
Upvotes: 1