简体   繁体   English

Mongodb:如何将 $lookup 和 map 的结果分组到包含匹配键的列表对象中?

[英]Mongodb: How to group the result of a $lookup and map them to a list objects that contain a matching key?

I have classroom document which contain 'modules', the whole document looks like this:我有包含“模块”的课堂文档,整个文档如下所示:

{
    "_id": "628a7ea21e2a666d7872efbf",
    "name": "Test Class",
    "owner": "60763491b98b9e186ef33137",
    "schoolId": "607dff27c712219af1e65d83",
    "description": "This is a test class.",
    "roster": [],
    "modules": [
        {
            "name": "Test Module 1",
            "id": "62a7082d0bf84c43fdfe95ff",
            "isPublished": false
        },
        {
            "name": "Test Module 2",
            "id": "62a72d6378ce044dca32e1a2",
            "isPublished": false
        }
    ]
}

I also have assignment documents as such:我也有这样的任务文件:

{
    "classroomId": "628a7ea21e2a666d7872efbf",
    "moduleId": "62a7082d0bf84c43fdfe95ff",
    "name": "Assignment 1",
    "description": "Test description",
    "created": 1655120822055,
    "reading": null,
    "questions": [],
    "isPublished": true,
    "_id": "62a723b6683ffc4b11940c7b"
}

My question is how could do aggregation such that if I want to do a lookup on the assignments for the classroom, I am able to group the assignment documents by moduleId and then add them as a field to the modules array.我的问题是如何进行聚合,以便如果我想查找课堂作业,我可以按 moduleId 对作业文档进行分组,然后将它们作为一个字段添加到模块数组中。 The final document would like this:最终文件是这样的:

{
    "_id": "628a7ea21e2a666d7872efbf",
    "name": "Test Class",
    "owner": "60763491b98b9e186ef33137",
    "schoolId": "607dff27c712219af1e65d83",
    "description": "This is a test class.",
    "roster": [],
    "modules": [
        {
            "name": "Test Module 1",
            "id": "62a7082d0bf84c43fdfe95ff",
            "isPublished": false,
            "assignments": [
                {
                    "_id": "62a708ab0bf84c43fdfe9600",
                    "classroomId": "628a7ea21e2a666d7872efbf",
                    "moduleId": "62a7082d0bf84c43fdfe95ff",
                    "name": "Assignment 1",
                    "description": "Test description",
                    "created": 1655113899629,
                    "due": null,
                    "settings": null,
                    "reading": null,
                    "questions": [],
                    "isPublished": true
                },
                {
                    "_id": "62a723b6683ffc4b11940c7b",
                    "classroomId": "628a7ea21e2a666d7872efbf",
                    "moduleId": "62a7082d0bf84c43fdfe95ff",
                    "name": "Assignment 1",
                    "description": "Test description",
                    "created": 1655120822055,
                    "due": null,
                    "settings": null,
                    "reading": null,
                    "questions": [],
                    "isPublished": true
                }
            ]

        },
        {
            "name": "Test Module 2",
            "id": "62a72d6378ce044dca32e1a2",
            "isPublished": false,
            "assignments": [

            ]
        }
    ]
}

Right now I just have the base lookup and obviously this just gets me a separate assignments field, without groups.现在我只有基本查找,显然这只是让我得到一个单独的分配字段,没有组。

lookup = [
    {
        $lookup: {
            from: "assignments",
            localField: "modules.id",
            foreignField: "moduleId",
            as: "assignments"
        }
    }
];
  1. $lookup

  2. $set - Set modules field. $set - 设置modules字段。

    2.1. 2.1. $map - Iterate the modules array and returns a new array. $map - 迭代modules数组并返回一个新数组。

    2.1.1. 2.1.1. $mergeObject - Merge current iterate module document with the document with assignments array from the result 2.1.1.1 . $mergeObject - 将当前迭代module文档与结果2.1.1.1中带有assignments数组的文档合并。

    2.1.1.1. 2.1.1.1。 $filter - Filter the assignments array by matching moduleId . $filter - 通过匹配moduleId过滤assignments数组。

  3. $unset - Remove assignments field. $unset - 删除assignments字段。

db.classroom.aggregate([
  {
    $lookup: {
      from: "assignments",
      localField: "modules.id",
      foreignField: "moduleId",
      as: "assignments"
    }
  },
  {
    $set: {
      modules: {
        $map: {
          input: "$modules",
          as: "module",
          in: {
            $mergeObjects: [
              "$$module",
              {
                "assignments": {
                  $filter: {
                    input: "$assignments",
                    as: "asgn",
                    cond: {
                      $eq: [
                        "$$module.id",
                        "$$asgn.moduleId"
                      ]
                    }
                  }
                }
              }
            ]
          }
        }
      }
    }
  },
  {
    $unset: "assignments"
  }
])

Sample Mongo Playground示例 Mongo 游乐场

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM