Is there a way to group a collection which looks like
[
{_id: "5bd258a7877e74059b6b65b2", year: 2017, title: "One"},
{_id: "5bd258a7877e74059b6b65b3", year: 2017, title: "Two"},
{_id: "5bd258a7877e74059b6b65b4", year: 2018, title: "Three"},
{_id: "5bd258a7877e74059b6b65b5", year: 2018, title: "Four"}
]
and output the result as
{
2017: [
0: {_id: "5bd258a7877e74059b6b65b2", title: "One", …}
1: {_id: "5bd258a7877e74059b6b65b3", title: "Two", …}
],
2018: [
0: {_id: "5bd258a7877e74059b6b65b4", title: "Three", …}
1: {_id: "5bd258a7877e74059b6b65b5", title: "Four", …}
]
}
using mongodb aggregations? Similar to how lodash groupBy
works
You can do that with the following mongoDB aggregation:
db.collection.aggregate([{
$group: {
_id: "$year",
docs: {
$addToSet: "$$CURRENT"
}
}
},
{
"$group": {
"_id": null,
"data": {
"$push": {
"k": {
$toString: "$_id"
},
"v": "$docs"
}
}
}
},
{
"$replaceRoot": {
"newRoot": {
"$arrayToObject": "$data"
}
}
}
])
You can see the result here
The idea is to group the data in a way where we can utilize $arrayToObject
. First group gives you the grouped by year where the second is just prep for $arrayToObject
which requires key, value
object. Last thing is the $replaceRoot
.
This requires MongoDB 3.6 and up due to $arrayToObject
being introduced in that version. Before that you had to use $push
etc.