Reputation: 61
Here is a sample document...
{
"_id": ObjectId("61c7969702f8612e6b14db57"),
"title": "Important Political Issue",
"comments": [
{
"_id": ObjectId("61c796a349a42520e5c1eba4"),
"comment": "This initiative should be passed",
"votes": [
{
"_id": ObjectId("61c797d7e7c81feb75c2a3e9"),
"value": 3,
"addedBy": ObjectId("61c65e3d912fa75c883bad7e"),
"addedDate": ISODate("2021-12-25T22:14:47.745Z")
},
{
"value": -1,
"addedBy": ObjectId("61c7406ce223cf753db8dd67"),
"_id": ObjectId("61c797d7e7c81feb75c2a3eb"),
"addedDate": ISODate("2021-12-25T22:14:47.746Z")
}
]
},
{
"_id": ObjectId("61c796a349a42520e5c1eba4"),
"comment": "This initiative should not be passed",
"votes": [
{
"_id": ObjectId("61c797d7e7c81feb75c2a3e9"),
"value": -5,
"addedBy": ObjectId("61c65e3d912fa75c883bad7e"),
"addedDate": ISODate("2021-12-25T22:14:47.745Z")
},
{
"value": 2,
"addedBy": ObjectId("61c7406ce223cf753db8dd67"),
"_id": ObjectId("61c797d7e7c81feb75c2a3eb"),
"addedDate": ISODate("2021-12-25T22:14:47.746Z")
},
{
"value": -3,
"addedBy": ObjectId("61c7406ce223cf753db8dd67"),
"_id": ObjectId("61c797d7e7c81feb75c2a3eb"),
"addedDate": ISODate("2021-12-25T22:14:47.746Z")
}
]
}
]
}
I would like to get something like this...
{
"_id" : ObjectId("61c7969702f8612e6b14db57"),
"title" : "Important Political Issue",
"comments" : [
{
"_id" : ObjectId("61c796a349a42520e5c1eba4"),
"comment" : "This initiative should be passed",
"voteSum": 4
},
{
"_id" : ObjectId("61c796a349a42520e5c1eba4"),
"comment" : "This initiative should not be passed",
"voteSum": -6
}
]
}
$project with $sum work perfectly for adding values from the "top level" array of a document...
db.issues.aggregate([
{$project: {
title: 1,
desc: 1,
voteSum: {$sum: '$votes.value'}
}}
])
However, I can't figure out how to make it $sum up values for in an array that is in another array.
This doesn't work, it yields zero (0) regardless of what I put in the comment vote values...
db.issues.aggregate([
{$project: {
_id: 1,
title: 1,
comments: {
_id: 1,
comment: 1,
voteSum: {$sum: '$comments.votes.value'}
}}
}
])
Upvotes: 1
Views: 59
Reputation: 20304
You can do it like this:
$map
: To iterate over comments array.$sum
: To sum all value
properties for votes array.db.collection.aggregate([
{
"$set": {
"comments": {
"$map": {
"input": "$comments",
"as": "comment",
"in": {
"_id": "$$comment._id",
"comment": "$$comment.comment",
"votes": {
"$sum": "$$comment.votes.value"
}
}
}
}
}
}
])
Upvotes: 0