1

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]},
     ]
 }
2
  • If you want them this way why are you grouping them? Commented Mar 8, 2022 at 15:51
  • Hello, i wanna plot this desire format to bar chat thats why am grouping them Commented Mar 8, 2022 at 15:57

1 Answer 1

2

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

Sign up to request clarification or add additional context in comments.

6 Comments

Can you please sort this by date.
sort is not difficult . which order to sort
res = {...res,series:Object.values(res.series),categories:res.categories.sort((a,b)=> new Date(a)-new Date(b))} for ascending. res = {...res,series:Object.values(res.series),categories:res.categories.sort((a,b)=> new Date(b)-new Date(a))} for descending
thanks for your response but I want to sort all data with date wise not just categories... right now just categories array is sorting not data array in series.
then you can the sort step just after the flatmap like a.flatMap(el => el.items).sort((a,b)=> new Date(a.date)-new Date(b.date)).reduce((acc.... and in the final answer just like res = {...res,series:Object.values(res.series)} without sort there
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.