Reputation: 7706
documents
[
{ _id: "a1",
selections:[
{_id:"s1", questionId:"q1", points:3, group:"no-group"},
{_id:"s2", questionId:"q2", points:2, group:"group-1"},
{_id:"s3", questionId:"q3", points:3, group:"no-group"},
{_id:"s4", questionId:"q4", points:7, group:"group-2"},
{_id:"s5", questionId:"q5", points:8, group:"group-2"},
{_id:"s6", questionId:"q6", points:9, group:"group-1"},
],
userId: "u1"
},
]
I am trying to create an aggregation that can group an array of objects get the multiple of the groups then sum the multiples. For example for the given document above the grouped array would look like below:
[
[
{_id:"s1", questionId:"q1", points:3, group:"no-group"},
{_id:"s3", questionId:"q3", points:3, group:"no-group"},
],
[
{_id:"s2", questionId:"q2", points:2, group:"group-1"},
{_id:"s6", questionId:"q6", points:9, group:"group-1"},
],
[
{_id:"s4", questionId:"q4", points:7, group:"group-2"},
{_id:"s5", questionId:"q5", points:8, group:"group-2"},
],
]
Then get multiples from all groups except the ones with group: "no-group"
. The ones for "no-group"
sum them instead of getting their multiple.
For example the grouped array would result to:
[
[3+3],// for no-group sum the points
[2*9],// for group-1 multiply the points
[7*8],// for group-2 multiply the points
]
// output = [ 6, 18, 56 ]
Then sum the output 6+18+56=80
.
How can I do this in mongodb aggregation? So I can get an output like
{ userId:"u1", totalPoints:"80" }
Upvotes: 0
Views: 3702
Reputation: 2290
How about this?
db.getCollection('col1').aggregate([
{ $unwind: '$selections' }, // unwrap initial selections array
{ $group: { _id: { user: '$userId', group: '$selections.group' }, points: { $push: '$selections.points' } } }, // group by user and group
{ $group: { _id: '$_id.user', totalPoints: { $sum: { // get the total sum for...
$cond:{
if: { $eq: ['$_id.group', 'no-group'] },
then: { $sum: '$points'}, // the sum of points if no-group
else: { $reduce: { input: '$points', initialValue: 1, in: { $multiply: ['$$value', '$$this']} } } // the multiplication of points for rest of cases
}
} } } }
])
Upvotes: 3