Let's say one has data below:
[
{ "_id" : 1, "last_name" : "Bernard", "first_name" : "Emil", "year_born" : 1868, "year_died" : 1941, "nationality" : "France" },
{ "_id" : 2, "last_name" : "Rippl-Ronai", "first_name" : "Joszef", "year_born" : 1861, "year_died" : 1927, "nationality" : "Hungary" }
]
Then runs $bucket
stage :
db.artists.aggregate( [
{
$bucket: {
groupBy: "$year_born", // Field to group by
boundaries: [ 1840, 1850, 1860, 1870, 1880 ], // Boundaries for the buckets
default: "Other", // Bucket ID for documents which do not fall into a bucket
output: { // Output for each bucket
"count": { $sum: 1 },
"artists" :
{
$push: {
"name": { $concat: [ "$first_name", " ", "$last_name"] },
"year_born": "$year_born"
}
}
}
}
}
] );
The output is like this:
{
"_id" : 1860,
"count" : 2,
"artists" : [
{ "name" : "Emil Bernard", "year_born" : 1868 },
{ "name" : "Joszef Rippl-Ronai", "year_born" : 1861 }
]
}
Example reference: MongoDB $bucket aggregation
-- Question --
Lower boundary is 1860 which is represented in the _id
field, but how to get the upper boundary which is 1870?
Thank you!
There's no Mongo-y way to do this.
If the years are hard coded you can just add this custom logic with an $addFields
, like so:
{
$addFields: {
upperBound: {
$sum: [
"$_id",
10
]
}
}
}
Mongo Playground
If they are passed dynamically you can use a similar approach and just extract the next element in the array:
const boundaries: [ 1840, 1850, 1860, 1870, 1880 ]
db.collection.aggregate([
{
$bucket: {
groupBy: "$year_born",
// Field to group by
boundaries: boundaries,
// Boundaries for the buckets
default: "Other",
// Bucket ID for documents which do not fall into a bucket
output: {
// Output for each bucket
"count": {
$sum: 1
},
"artists": {
$push: {
"name": {
$concat: [
"$first_name",
" ",
"$last_name"
]
},
"year_born": "$year_born"
}
}
}
}
},
{
$addFields: {
upperBound: {
"$arrayElemAt": [
boundaries,
{
$sum: [
{
"$indexOfArray": [
boundaries,
"$_id"
]
},
1
]
}
]
}
}
}
])
Mongo Playground
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With