$lookup for aggregation for two layer relationship

一个人想着一个人 提交于 2020-02-25 03:41:18

问题


Let me preface this by saying I may have not designed the User and corporation relationship correctly by not denormalizing, but how can I do it with what I have?

Lets say I have the following document in my collection Classes Collecton


  {
    "_id": ObjectId("5df58d45244a850d54b922c8"),
    "mentors" : {
        "numOfMentors" : NumberInt(1), 
        "mentorList" : [
            ObjectId("5c9ba636347bb645e0865283")
        ]
    },
    "lessons": [
      {
        "_id": ObjectId("5db221be211d7b68ac8be618"),
        "mentorData": {
          "objective": "Ensuring students that making mistakes is normal and that it is a part of life",
          "task": "Post a video explaining obstacles that you had to overcome as a programmer",
          "dueDate": "2019-12-14T15:26:10.000+0000"
        },
        "studentData": {
          "objective": "Learning that failures help you grow",
          "task": "Post a video explaining obstacles that you have overcame",
          "dueDate": "2020-01-14T22:26:10.000+0000" <---- CHECKING THIS DATE
        },
        "title": "How to overcome obstacles",
        "comments": []
      }
    ]    
  }

And I have the following user that is in the mentors.mentorList

{ 
    "_id" : ObjectId("5c9ba636347bb645e0865283"), 
    "securityQuestions" : {
        "isSetup" : false
    }, 
    "videos" : [

    ], 
    "events" : [

    ], 
    "name" : "Jackie Uphill", 
    "email" : "laura@stemuli.net", 
    "password" : "$2y$10$cmCZ.bnS/qK25wqp9i4bB.RMmctxd02Rlmc/cGN5XmUh46GMYigWu", 
    "account_type" : "volunteer", 
    "district" : "Dallas", 
    "date" : ISODate("2019-03-27T16:35:02.968+0000"), 
    "__v" : NumberInt(0), 
    "chat" : ObjectId("5c9ba637347bb645e0865284"), 
    "corporation" : ObjectId("5d83749fb57cc711487f1cc2"), 
    "profile" : ObjectId("5c9ba637347bb645e0865286"), 
    "profile_type" : "VolunteerProfile", 

}



There corporation is:

{ 
    "_id" : ObjectId("5d83749fb57cc711487f1cc2"), 
    "name" : "STEMuli Education"

}

And I am aggregating as follows:


  Class.aggregate([
            { $match: { "students.studentList": req.user._id } },
            { $unwind: "$lessons" },
            {
              $addFields: {
                date: {
                  $dateToString: {
                    format: "%Y-%m-%d",
                    date: "$lessons.studentData.dueDate"
                  }
                }
              }
            },
            {
              $match: {
                $and: [
                  { date: { $gte: startDate } },
                  { date: { $lte: endDate } }
                ]
              }
            },
            { $group: { _id: "$_id", lessons: { $push: "$lessons" } } }
          ])

Which returns this...

 {
            "lessonImage": {
                "url": "https://stemsandbox.blob.core.windows.net/stemuli/lesson-picture-a406bd19-0677-4b60-909e-7de2ca3c6f93.jpg",
                "originalname": "nintendo-switch-console.jpg",
                "mimetype": "image/jpeg",
                "blobName": "lesson-picture-a406bd19-0677-4b60-909e-7de2ca3c6f93.jpg",
                "container": "stemuli",
                "blob": "lesson-picture-a406bd19-0677-4b60-909e-7de2ca3c6f93.jpg",
                "size": "147469",
                "etag": "\"0x8D797B8F1EC9C39\"",
                "createdOn": "2020-01-12T23:41:28.588Z"
            },
            "_id": "5db221be211d7b68ac8be619",
            "mentorData": {
                "objective": "Learn to make a single web page web app",
                "task": "Create a short video instructing how to setup environment",
                "dueDate": "2019-02-02T22:26:10.000Z"
            },
            "studentData": {
                "objective": "Program a single page web app in React",
                "task": "Program a single page web app in React and submit by october 30th",
                "dueDate": "2020-01-22T22:26:10.000Z"
            },
            "title": "Learning to program in React",

        }

I want it to be like this I want to populate the mentor AND the corporation Note mentors field

 {
            "lessonImage": {
                "url": "https://stemsandbox.blob.core.windows.net/stemuli/lesson-picture-a406bd19-0677-4b60-909e-7de2ca3c6f93.jpg",
                "originalname": "nintendo-switch-console.jpg",
                "mimetype": "image/jpeg",
                "blobName": "lesson-picture-a406bd19-0677-4b60-909e-7de2ca3c6f93.jpg",
                "container": "stemuli",
                "blob": "lesson-picture-a406bd19-0677-4b60-909e-7de2ca3c6f93.jpg",
                "size": "147469",
                "etag": "\"0x8D797B8F1EC9C39\"",
                "createdOn": "2020-01-12T23:41:28.588Z"
            },
            "_id": "5db221be211d7b68ac8be619",
            "mentorData": {
                "objective": "Learn to make a single web page web app",
                "task": "Create a short video instructing how to setup environment",
                "dueDate": "2019-02-02T22:26:10.000Z"
            },
            "studentData": {
                "objective": "Program a single page web app in React",
                "task": "Program a single page web app in React and submit by october 30th",
                "dueDate": "2020-01-22T22:26:10.000Z"
            },
            "title": "Learning to program in React",
            "classId": "5e1baea87fcee8639cbce29d",\
          //FIELD BELOW ADDED
            "mentors": [ 
                {
                   "name" : "Jackie Uphill", 
                   "corporation": {"name": "Jedi Academy"}

                 }
                  ]
        }

回答1:


You can run below $lookup with custom pipeline to bring the data from other collections:

{
    $lookup: {
        from: "users",
        let: { mentor_ids: "$mentors" },
        pipeline: [
            { $match: { $expr: { $in: ["$_id",  "$$mentor_ids" ] } } },
            {
                $lookup: {
                    from: "corporation",
                    localField: "corporation",
                    foreignField: "_id",
                    as: "corporation"
                }
            },
            { $unwind: "$corporation" },
            {
                $project: {
                    name: 1,
                    "corporation.name": 1
                }
            }
        ],
        as: "mentors"
    }
}

Mongo Playground



来源:https://stackoverflow.com/questions/59866703/lookup-for-aggregation-for-two-layer-relationship

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!