When aggregating a collection with the following pipeline stages
let ap = [{
$group: {
_id: {
year: { $year: '$itemDate' },
month: { $month: '$itemDate' },
},
count: { $sum: 1 },
},
}]
I receive something like this…
[
{ _id: { year: 2022, month: 9 }, count: 2 },
{ _id: { year: 2022, month: 4 }, count: 232 },
{ _id: { year: 2022, month: 3 }, count: 259 },
{ _id: { year: 2022, month: 8 }, count: 12 },
{ _id: { year: 2022, month: 1 }, count: 76 }
]
I would like to use an $addFields
stage (or similar) such that my results would have a key and be sorted by year-month, like this
[
{ _id: { year: 2022, month: 1 }, count: 76, key: '2022-01'},
{ _id: { year: 2022, month: 3 }, count: 259, key: '2022-03'},
{ _id: { year: 2022, month: 4 }, count: 232, key: '2022-04'},
{ _id: { year: 2022, month: 8 }, count: 12, key: '2022-08'},
{ _id: { year: 2022, month: 9 }, count: 2, key: '2022-09'},
]
I have tried a template string, but it does not work. I also don’t know how this would be sortable either…
ap.push({
$addFields: {
key: `${'$_id.year'}-${'$_id.month'}`,
key2: '$_id.year',
},
});
Any help is greatly appreciated.
3
Answers
Use
$concat
to chain up the result from$toString
Mongo Playground
You can use a 3-step aggregation pipeline using
$project
,$group
and$sort
. It can look something like this:Option 1:
You don’t need a separate key to sort. Just sort on
_id.year
and_id.month
.Demo
Option 2:
Instead of having another stage, create the field in $group stage itself. Convert the date to string and pick the $first from the group.
Demo