I've got two models
Opinion {
_id: string;
creator: string;
teacher: ObjectId;
text: string;
date: Date;
}
Teacher {
_id: string;
name: string;
isVerified: boolean;
}
I need to get 3 latest Opinions WHERE { teacher.isVerified: true }
I tried
const newOpinions = await Opinion.find(
null,
"creator teacher text",
{
sort: {
date: -1,
},
}).populate(
{
path: 'teacher',
model: 'Teacher',
select: 'name',
match: {
isVerified: true,
},
}
).limit(3);
but (after short analysis) it works as designed - I'm getting 3 latest opinions, no matter if teachers is verified or not (in teacher field I'm getting null
if it's not verified)
Can anyone try to point me in the right direction? I think maybe something with Model.aggregate()
.
This is one way to do it. With this one you will filter the teachers first. Please also consult $lookup
documentation
Teacher.aggregate([{
$match: { isVerified: true }
}, {
$lookup: {
from: 'opinions' // assume you have collection named `opinions` for model `Opinion`,
localField: '_id', // join teacher._id ...
foreignField: 'teacher', // ... with opionion.teacher
as: 'opinions'
} // from here you well get verified teachers with embedded opinions,
// further stages are optional. We will modify the shape of output to be opinions only
}, {
$unwind: '$opinions' // spread out opinions array into separate documents
}, {
$replaceRoot: '$opinions' // replace the root document with opinion only
}])
The equivalent of join in mongodb is $lookup. A mongoose way is to use populate but you'll have to provide ref key in your model
For lookup usage https://docs.mongodb.com/manual/reference/operator/aggregation/lookup/
Mongoose Ref
Opinion {
_id: string;
creator: string;
teacher: {
type: Schema.Types.ObjectId, ref: 'Teacher'
},
text: string;
date: Date;
}
Teacher {
_id: string;
name: string;
isVerified: boolean;
}
The $lookup approach is much more flexible and customizable
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.