I have two collections with name School & Students
School Collection
{
_id: ObjectId("60008e81d186a82fdc4ff2b7"),
name: String,
branch: String,
class: [{
"active" : true,
"_id" : ObjectId("6001e6871d985e477b61b43f"),
"name" : "I",
"order" : 1
},
{
"active" : true,
"_id" : ObjectId("6001e68f1d985e477b61b444"),
"name" : "II",
"order" : 2
}]
}
Student Collection
{
_id: ObjectId("6002def815eccd53a596f830"),
schoolId: ObjectId("60008e81d186a82fdc4ff2b7"),
sessionId: ObjectId("60008e81d186a82fdc4ff2b9"),
class: ObjectId("6001e6871d985e477b61b43f"),
}
I want to get the data of Student Collection in single query.
I have class id
stored in Student Collection and data against that id
is stored in School Collection under class key, which is array of objects.
Can you please help me in getting the class object in student collection with this id?
Output i want:
data: {
_id: ObjectId("6002def815eccd53a596f830"),
schoolId: ObjectId("60008e81d186a82fdc4ff2b7"),
sessionId: ObjectId("60008e81d186a82fdc4ff2b9"),
class: ObjectId("6001e6871d985e477b61b43f"),
classData: [{
"active" : true,
"_id" : ObjectId("6001e6871d985e477b61b43f"),
"name" : "I",
"order" : 1
}]
}
So I tried this but it didn't work:
const students = await this.studentModel.aggregate([
{
$lookup: {
from: 'School',
let: { classId: '$class' },
pipeline: [
{
$match: {
$expr: { $eq: ['$$classId', '$class._id'] },
},
},
],
as: 'classData',
},
},
]);
$lookup
, pass schoolId
and class
in let
,$match
school id condition$filter
to iterate loop of class
and filter specific class object$arrayElemAt
will get object from returned result from $filter
$replaceRoot
to replace object to rootconst students = await this.studentModel.aggregate([
{
$lookup: {
from: "School",
let: {
schoolId: "$schoolId",
classId: "$class"
},
pipeline: [
{ $match: { $expr: { $eq: ["$$schoolId", "$_id"] } } },
{
$replaceRoot: {
newRoot: {
$arrayElemAt: [
{
$filter: {
input: "$class",
cond: { $eq: ["$$this._id", "$$classId"] }
}
},
0
]
}
}
}
],
as: "classData"
}
}
])