【问题标题】:How to groupby on a field value that is inside an array in MongoDB?如何对 MongoDB 中数组内的字段值进行分组?
【发布时间】:2021-10-06 12:56:55
【问题描述】:

我有使用 MongoDB 的学生评分系统。我在 MongoDB 中有以下文档:

我如何获取特定subject 获得grade "A","B","C","D" 的学生人数。每个主题的“_id”保持不变。

{
  _id: "60b223541338467beaf3ae0d",
  studentName: "John Doe"
  studentGradingDetails: [
    {
      _id: "60b21e47e5462929cab27a98",
      term: "semester-1",
      subject: "chemistry",
      grade: "A",
      createdAt: "2021-05-29T10:58:15.113Z",
    },
    {
      _id: "60b21e47e5462929cab27a99",
      term: "semester-2",
      subject: "computer_science",
      grade: "B",
      createdAt: "2021-05-29T10:58:15.113Z",
    },
  ],
  createdAt: "2021-05-29T11:19:48.770Z",
}
{
  _id: "60b223541338467beaf3ae0e",
  studentName: "Will Smith"
  studentGradingDetails: [
    {
      _id: "60b21e47e5462929cab27a98",
      term: "semester-1",
      subject: "chemistry",
      grade: "D",
      createdAt: "2021-05-29T10:58:15.113Z",
    },
    {
      _id: "60b21e47e5462929cab27a99",
      term: "semester-2",
      subject: "computer_science",
      grade: "A",
      createdAt: "2021-05-29T10:58:15.113Z",
    },
  ],
  createdAt: "2021-05-29T11:19:48.770Z",
}

这是我尝试并坚持的,不知道接下来的步骤是什么!?


await db.collection("studentsemestergrades")
        .aggregate([
            { $unwind: "$studentGradingDetails" },
            {
                $group: {
                    _id: "$studentGradingDetails._id",
                    
                },
            },
        ])
        .toArray();

预期输出:

每个科目得分不同的学生分布(_id)

{
  "_id" : "60b21e47e5462929cab27a98",
  "A" : 12,
  "B" : 20,
  "C" : 8,
  "D" : 2
},
{
  "_id" : "60b21e47e5462929cab27a99",
  "A" : 5,
  "B" : 2,
  "C" : 8,
  "D" : 12
}

【问题讨论】:

    标签: node.js mongodb aggregate-functions


    【解决方案1】:
    • $unwind 解构 studentGradingDetails 数组
    • $group by _idgrade 并获得总数
    • $group 仅由_idgradecount 构造对象的键值对数组
    • $arrayToObject将上面的键值对数组转换为对象
    • $mergeObjects 合并以上转换后的对象和 _id 字段,如果需要,您可以添加更多字段
    • $replaceRoot 将上面的合并对象替换为根
    await db.collection("studentsemestergrades").aggregate([
      { $unwind: "$studentGradingDetails" },
      {
        $group: {
          _id: {
            _id: "$studentGradingDetails._id",
            grade: "$studentGradingDetails.grade"
          },
          count: { $sum: 1 }
        }
      },
      {
        $group: {
          _id: "$_id._id",
          grades: {
            $push: {
              k: "$_id.grade",
              v: "$count"
            }
          }
        }
      },
      {
        $replaceRoot: {
          newRoot: {
            $mergeObjects: [
              { _id: "$_id" },
              { $arrayToObject: "$grades" }
            ]
          }
        }
      }
    ])
    

    Playground

    【讨论】:

      猜你喜欢
      • 2018-07-15
      • 2023-01-20
      • 2019-01-02
      • 2023-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-14
      相关资源
      最近更新 更多