我读到你可以制作Mongoose auto pouplate ObjectId字段。但是,我在构建查询以填充子文件中的字段时遇到了问题。
我的模特:
var QuestionSchema = new Schema({
question_text: String,
type: String,
comment_field: Boolean,
core_question: Boolean,
identifier: String
});
var SurveyQuestionSchema = new Schema({
question_number: Number,
question: {type: Schema.Types.ObjectId, ref: 'Question', required: true} //want this popuplated
});
var SurveySchema = new Schema({
start_date: Date,
end_date: Date,
title: String,
survey_questions: [SurveyQuestionSchema]
});
现在我通过以下方式实现了这个效果:
Survey.findById(req.params.id, function(err, data){
if(err || !data) { return handleError(err, res, data); }
var len = data.survey_questions.length;
var counter = 0;
var data = data.toJSON();
_.each(data.survey_questions, function(sq){
Question.findById(sq.question, function(err, q){
sq.question = q;
if(++counter == len) {
res.send(data);
}
});
});
});
这显然是一种非常容易出错的方式...
答案 0 :(得分:0)
正如我在上面的评论中所指出的,这是一个目前正由mongoose团队审查的问题(尚未实施)。
另外,从局外人的洞察中看你的问题,我首先想到的是改变架构以消除SurveyQuestion
,因为它有一个非常关系的数据库“加入”模型的感觉。 Mongoose嵌入式集合具有静态排序顺序,无需保留位置字段,如果您可以在Survey
本身处理问题选项,则会降低模式复杂性,因此您不需要执行双重操作-populate。
话虽如此,通过一次查询所有问题,你可以将查询减少到2,例如:
Survey.findById(req.params.id, function(err, data){
if(err || !data) { return handleError(err, res, data); }
var data = data.toJSON();
var ids = _.pluck(data.survey_questions, 'question');
Question.find({_id: { $in: ids } }, function(err, questions) {
_.each(data.survey_questions, function(sq) {
sq.question = _.find(questions, function(q) {
var id = q._id.toString();
return id == sq.question;
});
});
res.send(data);
});
});