There was also a typo in your code. The params name is id, so it should be req.params.id and not req.params._id - that's probably the reason why you were receiving an empty array.
For your case, you can filter the result so that you only receive the project member of a specific id through aggregation.
For example:
app.get('/stu/:id', (req, res) => {
try {
const student = await ProjectSchema.aggregate([
{
$project: {
_id: 0,
projectmembers: {
$filter: {
input: "$projectmembers",
as: "projectMember",
cond: {
$eq: [
"$$projectMember._id",
ObjectId(req.params.id)
]
}
}
}
}
}
]);
if (!student)
return res.status(400).json({
success: false,
message: "No student exists with this ID",
});
return res.status(200).json({
success: true,
message: "Student Found",
studentDetails: student,
});
} catch (err) {
return res.status(500).json({
success: false,
message: "Error encountered whilst finding student",
error: err,
});
}
});
You can see that there is a $project stage - what this does is tells mongo what you want to return. I wrote _id: 0, which tells mongo that you do not want to return the document's _id field. Then the $filter stage has an input field, which tells mongo what to filter - in our case projectmembers. In the $as field is the name of the variable for each item in your projectmembers array, which I named projectMember - you could name it anything you like. Then we can access each item via the variable named projectMember in our condition statement cond we passed an $eq condition, which checks the projectmembers array for any $$projectMember._id (in the eq condition, we prefix projectMember.id with two $$ in order to access it) which is equal to req.params.id.
To access the ObjectId, you will need to import it at the top of your file:
const { ObjectId } = require("mongodb");
Finally, you can also see how the mongo aggregation works here at Mongo Playground and play around with it.