MongoDB Nodejs中唯一键的聚合响应格式

MongoDB Aggregation response format to unique key in Nodejs

我从 mongoDB 聚合查询得到响应,它是分组数据和 select 动态字段,它在“projectionObj”对象上:

这是我的mongodb 聚合查询:

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

下面是聚合结果:

[
 {
  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'
    }]
  }
]

我想将聚合结果格式化为下面给出的所需格式

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

首先我在数组上 运行 flatMap 并得到了一个包含单个项目的数组。然后 运行 reduce 根据名称对 series 进行分组,并将日期添加到 categories.
但是现在系列是一个对象。根据需要将其转换为数组我在最终结果中覆盖 series 以使用 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; }