My project is in nodeJs with express and i use mongoose for the request to my database mongoDb.
I have a model Media
the structure is:
{ "_id": { "$oid": "6354f982a11464ff4f7bac60" }, "userId": { "$oid": "6353aa119d39ccbb3263123f" }, "date": "2022-10-23", "base64": "data:image/png;base64,iVBORw0KGgoAAA....=", "label": "Noamount", "uriPath": "xxxx", "s3Path": "xxxx", "amount": 0, "__v": 0, "type": "tva" }
Like you seen there is a field date, imagine that i have 3 medias on differents month:
{ "date": "2022-10-23", "label": "monthTen", "type" : "tva", ... // Other property }, { "date": "2022-09-10", "label": "monthNineFirst", "type" : "tva", ... // Other property }, { "date": "2022-09-19", "label": "monthNineSecond", "type" : "other", ... // Other property }
I want to output something like this:
// Ordery by type in first place and by month // number like 9 = the month inside the date property { tva: { 9: [{ label: "monthNineFirst"... }], 10: [{ label: "monthNineTen"... }] }, other: { 9: [{ label: "monthNineSecond"... }] } }
Is found the property aggregate
but i don’t understand it correctly.
I know how to dow that in JS it’s easy, but can i do that directly on the request with the property aggregate
and $group
?
There is what i have done so far https://mongoplayground.net/p/-vAbdnnqOfD
Advertisement
Answer
Here’s one way to do it by extending your mongoplayground.net
start.
db.collection.aggregate([ { // group all docs by month $group: { _id: { $month: { $dateFromString: { dateString: "$date", format: "%Y-%m-%d" } } }, data: {"$push": "$$ROOT"} } }, { // group all groups into a single doc "$group": { "_id": null, "groupData": { "$push": { // k,v for $arrayToObject "k": "$_id", "v": { "$sortArray": { "input": "$data", "sortBy": {"date": 1} } } } } } }, { "$replaceWith": { "$arrayToObject": { "$map": { "input": { // sort by month "$sortArray": { "input": "$groupData", "sortBy": {"k": 1} } }, "in": { "$mergeObjects": [ "$$this", { // rewrite k as string "k": {"$toString": "$$this.k"} } ] } } } } } ])
Try it on mongoplayground.net.