Reputation: 471
I would like to migrate one of my FireBase projects to Mongo and move the calculations from server side to DB. I already wrote most of the queries but this one is beyond my knowledge.
Player data are saved by week and I need to calculate the sum of donations
and points
for each players
(the rest of the fields should be ignored).
PS: Some of the players are already banned so it would be enough the calculate the fields for a given player set (like: tag
in ['playerId1', 'playerId2', ...]
). If it's too complex I will do this filtering later on server side.
[
{
"week":"2021-01",
"players":[
{
"donations":20,
"games":3,
"name":"Player1",
"points":258,
"tag":"playerId1"
},
{
"donations":37,
"games":5,
"name":"Player2",
"points":634,
"tag":"playerId2"
},
{ ... }
]
},
{
"week":"2021-02",
"players":[ { ... } ]
}
]
So the result should be something like this:
[
{
"name":"Player1",
"tag":"playerId1",
"donations":90,
"points":980
},
{
"name":"Player2",
"tag":"playerId2",
"donations":80,
"points":1211
}
]
I think the $unwind
and the $group
operators could be the key but I can't figure out how to use them properly here.
Upvotes: 0
Views: 51
Reputation: 36144
$unwind
deconstruct players
array$group
by name and get sum of donations
and points
and get first tag
$project
to show required fieldsdb.collection.aggregate([
{ $unwind: "$players" },
{
$group: {
_id: "$players.name",
donations: { $sum: "$players.donations" },
points: { $sum: "$players.points" },
tag: { $first: "$players.tag" }
}
},
{
$project: {
_id: 0,
name: "$_id",
points: 1,
tag: 1,
donations: 1
}
}
])
PS: Some of the players are already banned so it would be enough the calculate the fields for a given player set (like: tag in ['playerId1', 'playerId2', ...]).
You can put match condition after $unwind
stage,
{ $match: { "players.tag": { $in: ['playerId1', 'playerId2', ..more] } } }
Upvotes: 1
Reputation: 22974
You were right,
db.collection.aggregate([
{//Denormalize
"$unwind": "$players"
},
{//Group by name
"$group": {
"_id": "$players.name",
"donations": {
"$sum": "$players.donations"
},
"points": {
"$sum": "$players.points"
},
}
}
])
You can add project
stage if you really need name
as key than _id
Upvotes: 1