MongoDB聚合: array of objects sum with group by

标签 mongodb

有了下面的示例数据,我正在尝试获取学生的总数以及每个主题的组合topScore 部分地板:

[{
  "section": "east",
  "floor": "1st",
  "classrom": 100,
  "tests": [
  {
    "subject": "math",
    "students": 30,
    "topScore": 90
  },
  {
    "subject": "english",
    "students": 40,
    "topScore": 80
  }]
},
{
  "section": "east",
  "floor": "1st",
  "classrom": 150,
  "tests": [
  {
    "subject": "math",
    "students": 35,
    "topScore": 85
  },
  {
    "subject": "english",
    "students": 45,
    "topScore": 70
  }]
}]

期望的结果:

[{
  "section": "east",
  "floor": "1st",
  "classroms": [100, 150],
  "tests": [
  {
    "subject": "math",
    "totalStudents": 65,
    "combinedTopScores": 175
  },
  {
    "subject": "english",
    "totalStudents": 85,
    "combinedTopScores": 150
  }]
}]

到目前为止我所拥有的是:

db.collection.aggregate([{
  "$group": {
    "_id": {
      "section": "$section",
      "floor": "$floor"
    },
    "classrooms": { "$push": "$classroom" },
    "tests": { "$push": "$tests" }
  }
}])

这给了我:

{
  "_id":
  {
    "section": "east",
    "floor": "1st"
  },
  "classrooms": [100, 150],
  "tests": [
    [{
      "subject": "math",
      "students": 30,
      "topScore": 90
    },
    {
      "subject": "english",
      "students": 40,
      "topScore": 80
    }],
    [{
      "subject": "math",
      "students": 35,
      "topScore": 85
    },
    {
      "subject": "english",
      "students": 45,
      "topScore": 70
    }]
  ]
}

所以我很难计算出 tests 数组的 $sum 。特别是因为它必须按主题分组。

有人能给我指个方向吗?这可能吗?

谢谢!

最佳答案

您需要$unwind 测试数组能够按section+floor+subject分组。然后,您可以计算总计并仅通过 section + floor 执行第二个 $group 阶段。由于 classroms 将是一个数组数组,并且可能包含重复项,因此您可以使用 $reduce$setUnion展平这些数组并删除重复的值。尝试:

db.collection.aggregate([
    { $unwind: "$tests" },
    {
        $group: {
            _id: {
                section: "$section",
                floor: "$floor",
                subject: "$tests.subject"
            },
            totalStudents: { $sum: "$tests.students" },
            combinedTopScores: { $sum: "$tests.topScore" },
            classroms: { $push: "$classrom" }
        }
    },
    {
        $group: {
            _id: { section: "$_id.section", floor: "$_id.floor" },
            classroms: { $push: "$classroms" },
            tests: {
                $push: {
                    subject: "$_id.subject",
                    totalStudents: "$totalStudents",
                    combinedTopScores: "$combinedTopScores"
                }
            }
        }
    },
    {
        $project: {
            section: "$_id.section",
            floor: "$_id.floor",
            classroms : {
                $reduce: {
                    input: "$classroms",
                    initialValue: [],
                    in: { $setUnion: [ "$$this", "$$value" ] }
                }
            },
            tests: 1
        }
    }
])

关于MongoDB聚合: array of objects sum with group by,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52177349/

相关文章:

javascript - Mongoose.connection ('once' ) 是什么意思

node.js - 集合显示但文档未显示在 mongoDB 中

mongodb - 在mongoDB中通过_id搜索效率更高吗?

mongodb - 在 mongoimport --jsonArray 上的子文档上创建 _id

javascript - 如何在不发送太多请求的情况下通过前端在每次鼠标单击时更新我的​​数据库?

mongodb - MongoDB $push 运算符是添加嵌入式文档的方式吗?

mongodb - 从 pig 写入 mongodb 时出错

database - 多次插入 mongodb - 只有第一个集合得到更新

MongoDB:查找数组中元素具有空值的记录

mongodb - 更新 Mongodb 中的多嵌套数组