I have MongoDB database with lot of different coins and need to aggregate them in multilevel output but not sure how. I am using mongoose in backend and need to create route with express that will get coins and sort them in the way that I need in order to be easier for me on frontend side inside app. I found lot of examples of multilevel group here but non of them did not match my situation and I can get it work.
INPUT:
[
{
"_id": "643d5bf4637daa055466d8f0",
"country": "AND",
"denomination": 0.01,
"series": 1
},
{
"_id": "643d5bf4637daa055466d8f0",
"country": "AND",
"denomination": 0.01,
"series": 1
},
{
"_id": "643d5bf4637daa055466d8f0",
"country": "BEL",
"denomination": 0.01,
"series": 1
},
{
"_id": "643d5bf4637daa055466d8f0",
"country": "BEL",
"denomination": 0.02,
"series": 1
},
{
"_id": "643d5bf4637daa055466d8f0",
"country": "BEL",
"denomination": 0.5,
"series": 2
},
{
"_id": "643d5bf4637daa055466d8f0",
"country": "ESP",
"denomination": 0.2,
"series": 1
},
{
"_id": "643d5bf4637daa055466d8f0",
"country": "ESP",
"denomination": 0.05,
"series": 3
}
]
and I need output like this
OUTPUT:
[
{
"country": "AND",
"series": [
{
"series": 1,
"coins": [
{
"_id": "643d5bf4637daa055466d8f0",
"country": "AND",
"denomination": 0.01,
"series": 1
},
{
"_id": "643d5bf4637daa055466d8f0",
"country": "AND",
"denomination": 0.01,
"series": 1
}
]
}
]
},
{
"country": "BEL",
"series": [
{
"series": 1,
"coins": [
{
"_id": "643d5bf4637daa055466d8f0",
"country": "BEL",
"denomination": 0.01,
"series": 1
},
{
"_id": "643d5bf4637daa055466d8f0",
"country": "BEL",
"denomination": 0.02,
"series": 1
}
]
},
{
"series": 2,
"coins": [
{
"_id": "643d5bf4637daa055466d8f0",
"country": "BEL",
"denomination": 0.5,
"series": 2
}
]
}
]
},
{
"country": "ESP",
"series": [
{
"series": 1,
"coins": [
{
"_id": "643d5bf4637daa055466d8f0",
"country": "ESP",
"denomination": 0.2,
"series": 1
}
]
},
{
"series": 3,
"coins": [
{
"_id": "643d5bf4637daa055466d8f0",
"country": "ESP",
"denomination": 0.05,
"series": 2
}
]
}
]
}
]
so far I got this done but don't know how to push coins in right series from this point.
const coins = await Coin.aggregate([
{
$group: {
_id: '$country',
series: { $addToSet: { series: '$series', coins: [] } },
},
},
{
$addFields: { country: '$_id' },
},
{
$project: {
_id: 0,
},
},
{
$sort: { country: 1 },
},
]);
a possible approach is
country
and series
country
only and push the grouped series and coins to a series arrayyou can see the intermediate stages on the Stage dropdown in the playground
db.collection.aggregate([
{ $group: { _id: { country: "$country", series: "$series" }, coins: { $push: "$$ROOT" } } },
{ $group: { _id: "$_id.country", series: { $push: { series: "$_id.series", coins: "$coins" } } } },
{ $addFields: { country: "$_id" } },
{ $project: { _id: 0 } },
{ $sort: { country: 1 } }
])
or you can $project
directly without $addFields
{ $project: { _id: 0, country: "$_id", series: 1 } }