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. 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"
}
}
];
CodePudding user response:
$lookup
$set
- Setmodules
field.2.1.
$map
- Iterate themodules
array and returns a new array.2.1.1.
$mergeObject
- Merge current iteratemodule
document with the document withassignments
array from the result 2.1.1.1.2.1.1.1.
$filter
- Filter theassignments
array by matchingmoduleId
.$unset
- Removeassignments
field.
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"
}
])