如何让猫鼬的 .populate() 与嵌入式架构/子文档一起工作?



我读到你可以让猫鼬自动弹出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);
            }
        });
    });
});

这显然是一种非常容易出错的方法......

正如我在上面的评论中指出的那样,这是猫鼬团队目前正在审查的问题(尚未实施)。

另外,从局外人的视角来看你的问题,我的第一个想法是更改模式以消除SurveyQuestion,因为它具有非常关系的数据库"连接"模型感觉。 Mongoose 嵌入式集合具有静态排序顺序,无需保留位置字段,并且如果您可以处理Survey本身的问题选项,它将降低架构复杂性,因此您无需进行双重填充。

话虽如此,您可以通过一次查询所有问题将查询减少到 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);
    });
});

最新更新