问题描述
{
courseName: String,teacher: ObjectId,students: [{type: ObjectId,ref: 'Student'}]
}
“学生”模式如下所示:
{
personalInfo: PersonalInfo,proffesionalInfo: {type: ObjectId,ref: 'ProffesionalInfo'}
}
“ProffesionalInfo”架构如下所示:
{
allgrades: [Number],averageGrade: Number,...
...
}
我有教室 _id,我只想让他们的平均成绩低于 90 的学生。 我现在的做法是这样的:
Classroom.findOne({ _id })
.populate("teacher","_id name")
.populate({
path: 'ridesstudents',select: 'proffesionalInfo',populate: [
{
path: "proffesionalInfo",select: "allgrades averageGrade"
}
]
})
.then(classroom => {
classroom.students = classroom.students.filter(student => student.proffesionalInfo.averageGrade < 90);
resolve(user);
})
.catch(err => reject(err));
如您所见,我在带齐所有学生后进行过滤。 如果我有 1000 万学生,只有 2 个成绩低于 90,这是“不好”的做法。
如何过滤查询中的学生而不是将所有学生都带上然后过滤??
旁注 - 以上数据只是一个示例,其目标是带来总体思路。不要深入细节。
解决方法
尝试使用聚合:
let classroom = Classroom.aggregate([
{ $match: { _id: classroomId } },{ $lookup: {
from: "students",localField: "_id",foreignField: "students",pipeline:[
{ $lookup: {
from: "professionalInfo",foreignField: "proffesionalInfo",as:"professionalInfo"
}},{ $match: {$lte: ["professionalInfo.averageGrade",90]}}
]
as: "students"
}}])