0

Mongooseが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);
            }
        });
    });
});

これは明らかにエラーが発生しやすい方法です...

4

1 に答える 1

0

上記のコメントで指摘したように、これは現在マングース チームによって精査されている問題です (まだ実装されていません)。

また、部外者の視点からあなたの問題を見ると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);
    });
});
于 2013-01-24T16:37:15.250 に答える