I have a collection which comprises of three level array nesting as shown below
_id: ObjectID('abc'),
sections: [
{
sectionId: "sec0",
sectionName: "ABC",
contents: [
{
contentId: 0,
tasks: [
{
taskId: ObjectID('task1')
}
//May contain 1-100 tasks
],
contentDescription: "Content is etc",
}
]
}
]
Sections is an array of objects which contains an object each with sectionId, and contents array which is an array of objects comprising of contentId, contentDescription, and nested array of tasks which comprises of an object containing a taskId. I am applying $lookup operator in order to join nested tasks array with tasks collection but I am facing a problem in document duplication as shown below.
_id: ObjectID('abc'),
sections: [
{
sectionId: "sec0",
sectionName: "ABC",
contents: [
{
contentId: 0,
tasks: [
{
//Task Document of ID 1
}
],
contentDescription: "Content is etc",
}
]
}
]
_id: ObjectID('abc'),
sections: [
{
sectionId: "sec0",
sectionName: "ABC",
contents: [
{
contentId: 0,
tasks: [
{
//Task Document of ID 2
}
],
contentDescription: "Content is etc",
}
]
}
]
Whereas the desired output is as follows
_id: ObjectID('abc'),
sections: [
{
sectionId: "sec0",
sectionName: "ABC",
contents: [
{
contentId: 0,
tasks: [
{
//Task Document of ID 1
},
{
//Task Document of ID 2
},
{
//Task Document of ID 3
}
],
contentDescription: "Content is etc",
}
]
}
]
In the collection, a sections array might contain multiple section object which might contain multiple contents and so on and so forth. The schema in question is temporary as our company is currently migrating from an existing database to MongoDB, so architectural refactoring is not possible atm and I need to work with existing schema design from different database.
I tried the following way
const contents= await sections.aggregate([
{
$match: { _id: id},
},
{ $unwind: '$sections' },
{
$unwind: {
path: '$sections.contents',
preserveNullAndEmptyArrays: true,
},
},
{
$unwind: {
path: '$sections.contents.tasks',
preserveNullAndEmptyArrays: true,
},
},
{
$lookup: {
from: 'tasks',
let: { task_id: '$sections.contents.tasks.taskId' },
pipeline: [
{ $match: { $expr: { $eq: ['$_id', '$$task_id'] } } },
],
as: 'sections.contents.tasks',
},
},
{
$addFields: {
'sections.contents.tasks': {
$arrayElemAt: ['$sections.contents.tasks', 0],
},
},
},
{
$group: {
_id: '$_id',
exam: { $push: '$sections.contents.tasks' },
},
},
]);
And I am also unable to use $group aggregation operator like
$group: {
_id: '$_id',
sections: {
sectionId : { $first: '$sectionId' },
sectionName: { $first: '$sectionName' },
contents: {
contentId: { $first: '$contentId' },
task: { $push: $sections.contents.tasks }
}
},
},
Any help or directions will be appreciated, I also searched on SO, and found this but couldn't understand the following part
{"$group":{
"_id":{"_id":"$_id","mission_id":"$missions._id"},
"agent":{"$first":"$agent"},
"title":{"$first":"$missions.title"},
"clients":{"$push":"$missions.clients"}
}},
{"$group":{
"_id":"$_id._id",
"missions":{
"$push":{
"_id":"$_id.mission_id",
"title":"$title",
"clients":"$clients"
}
}
}}