【问题标题】:How to Make Mongoose's .populate() work with an embedded schema/subdocument?如何使 Mongoose 的 .populate() 与嵌入式模式/子文档一起使用?
【发布时间】:2013-01-25 06:07:50
【问题描述】:

我了解到您可以将 Mongoose 设为自动 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);
            }
        });
    });
});

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

【问题讨论】:

  • 为此问题找到了 bug threadroadmap。都是当前的。
  • 谢谢@numbers1311407!很高兴知道。不过,我开始认为,必须有一种方法可以重组我的架构以使其适用于当前的实现。
  • 也许是一个愚蠢的问题(因为除此之外我对应用一无所知),但你真的需要SurveyQuestion 吗? Mongoose 数组的顺序是有保证的,所以你不需要对它们进行排序。在不了解应用程序的情况下查看它,它看起来像 Survey 可以嵌入 Questions。
  • 这个想法是稍后在 SurveyQuestion 中可以有一些修饰符字段,例如 required ,也许还有一个属性数组,这些属性可以扩展到问题
  • 顺便说一下上下文,这里是对应的backbone modelsmongoose models

标签: node.js mongoose populate


【解决方案1】:

正如我在上面的 cmets 中指出的,这是 mongoose 团队目前正在审查的问题(尚未实施)。

另外,从局外人的角度来看您的问题,我的第一个想法是更改架构以消除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);
    });
});

【讨论】:

  • 太棒了!最终使用了您的代码,但做了一些修改(修改了您的回复)。
猜你喜欢
  • 2016-09-28
  • 2020-05-15
  • 1970-01-01
  • 2018-03-30
  • 2019-01-06
  • 2012-02-23
  • 2013-06-29
  • 2015-10-14
  • 1970-01-01
相关资源
最近更新 更多