我有两个模式定义如下:
var WorksnapsTimeEntry = BaseSchema.extend({
student: {
type: Schema.ObjectId,
ref: 'Student'
},
timeEntries: {
type: Object
}
});
var StudentSchema = BaseSchema.extend({
firstName: {
type: String,
trim: true,
default: ''
// validate: [validateLocalStrategyProperty, 'Please fill in your first name']
},
lastName: {
type: String,
trim: true,
default: ''
// validate: [validateLocalStrategyProperty, 'Please fill in your last name']
},
displayName: {
type: String,
trim: true
},
municipality: {
type: String
}
});
我想遍历每个学生并显示它的时间条目。到目前为止,我的这段代码显然不正确,因为我仍然不知道如何加入 WorksnapTimeEntry 模式表。
Student.find({ status: 'student' })
.populate('student')
.exec(function (err, students) {
if (err) {
return res.status(400).send({
message: errorHandler.getErrorMessage(err)
});
}
_.forEach(students, function (student) {
// show student with his time entries....
});
res.json(students);
});
任何人都知道我该如何实现这一目标?
原文由 Lulzim 发布,翻译遵循 CC BY-SA 4.0 许可协议
您不希望
.populate()
在这里,而是您想要两个查询,其中第一个与Student
对象匹配以获取_id
值,$in
以匹配那些“学生”的相应WorksnapsTimeEntry
项目。使用
async.waterfall
只是为了避免一些缩进蠕变:如果你真的必须,那么你可以在第二个查询中
.populate("student")
从另一个表中获取填充的项目。相反的情况是查询
WorksnapsTimeEntry
并返回“一切”,然后使用“匹配”查询选项过滤掉来自.populate()
的任何null
结果:所以这不是一个可取的操作,因为“数据库”没有过滤可能的大部分结果。
除非您有充分的理由不这样做,否则您可能“应该”“嵌入”数据。这样,像
"status
之类的属性已经在集合中可用,并且不需要额外的查询。如果您使用的是像 MongoDB 这样的 NoSQL 解决方案,您应该接受它的概念,而不是坚持关系设计原则。如果您一直在进行关系建模,那么您不妨使用关系数据库,因为您不会从具有其他处理方式的解决方案中获得任何好处。