Home > Software design >  MongoDB Aggregation response format to unique key in Nodejs
MongoDB Aggregation response format to unique key in Nodejs

Time:03-09

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]},
     ]
 }

CodePudding user response:

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; }

  • Related