MongoDB Aggregation response format to unique key in Nodejs

I am getting response from mongoDB aggregation query which is grouped data and select fields dynamically which is on “projectionObj” object:

Here is my mongodb aggregation query:

   let projectionObj = {
          "date": 1,
          "height": 1,
          "bmi": 1,
          "level": 1,
    }

   UpdateForm.aggregate([
            { $match: {
                    "id": id,
                    "date": {
                        "$gte": startdate,
                        "$lte": enddate,
                    }}},
            { $group: {
                    _id: {
                        year: { $year: "$date" },
                        month: { $month: "$date" },
                        day: { $dayOfMonth: "$date" },
                    },
                    items: {
                        $push: '$$ROOT',
                    }}},
            {$project: {
                    "_id": 0,
                    "items": projectionObj
                }},
        ])

And below is aggregation result:

[
 {
  items: [{
    date: "2022-03-11",
    height: '1',
    bmi: '1',
    level: '1'
   },
   {
    date: "2022-03-11",
    height: '2',
    bmi: '2',
    level: '2'
   }]
},
{
  items: [{
    date: "2022-03-08",
    height: '3',
    bmi: '3',
    level: '3'
    }]
  }
]

I want to format aggregation result to desire able format which is given below

 {
   categories: ["2022-03-11", "2022-03-11", "2022-03-08"],
   series: [
          {name: "height", data: [1,2,3]},
          {name: "bmi", data: [1,2,3]},
          {name: "level", data: [1,2,3]},
     ]
 }

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

first I ran flatMap on the array and got an array of individual items. then ran reduce to group the series based on names and to add dates to categories.
But now series is an object. to convert it to an array as you need I overrode series in the final result to take the array of grouped values using Object.values

let a = [
 {
  items: [{
    date: "2022-03-11",
    height: '1',
    bmi: '1',
    level: '1'
   },
   {
    date: "2022-03-11",
    height: '2',
    bmi: '2',
    level: '2'
   }]
},
{
  items: [{
    date: "2022-03-08",
    height: '3',
    bmi: '3',
    level: '3'
    }]
  }
]

let res = a.flatMap(el => el.items).reduce((acc,{date,...curr})=>{
    acc.categories.push(date)
  Object.entries(curr).forEach(([k,v])=>{
    if(!acc.series[k])acc.series[k]={name:k,data:[]}
    acc.series[k].data.push(parseInt(v))
  })
  return acc;
},{categories:[],series:{}})

res = {...res,series:Object.values(res.series)}
console.log(res)
.as-console-wrapper { max-height: 100% !important; top: 0; }


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x