首页 > 解决方案 > Mongoose - 我怎样才能找到并列出链接到另一个集合?

问题描述

我正在尝试查找并显示“问题集合”中的所有问题,这些问题与我在“调查集合”中找到的用户创建的所有调查相关联,我能够在列表中找到特定调查的问题,但是我希望能够找到与不同调查相关的所有问题。

这是我到目前为止所拥有的,在这种情况下,我只使用 _id 查找特定于一项调查的问题:

// Display list of user surveys
module.exports.displayUserSurveys = (req, res, next) => {
  let id = req.user._id;

  Survey.find({ User: id }, (err, surveyList) => {
    if (err) {
      console.log(err);
      res.end(err);
    } else {
      let questionId = surveyList[0].Questions;
      Question.find({ _id: questionId }, (err, questionList) => {
        if (err) {
          return console.error(err);
        } else {
          let currentDate = new Date();
          res.render("content/survey/my-surveys", {
            title: "My Surveys",
            page: "my-surveys",
            username: req.user ? req.user.username : "",
            SurveyList: surveyList,
            QuestionList: questionList,
            today: currentDate,
          });
        }
      });
    }
  });
};

调查模式:

let surveyModel = mongoose.Schema(
  {
    Title: String,
    Type: [String],
    Questions: { type: mongoose.Schema.Types.ObjectId, ref: "questions" },
    Answered: { type: Number, default: 0 }, // how many times users answered
    User: { type: mongoose.Schema.Types.ObjectId, ref: "users" },
    startdate: { type: Date, default: Date.now },
    enddate: { type: Date, default: Date.now() + 30 * 24 * 60 * 60 * 1000 }, //30 days to milliseconds to set default end date 30 days out
  },
  {
    collection: "surveys",
  }
);

问题架构:

let questionModel = mongoose.Schema(
  {
    MC: {
      startdate: Date,
    enddate: Date,
      QuestionText1: String,
      Options1: [String],
      QuestionText2: String,
      Options2: [String],
      QuestionText3: String,
      Options3: [String],
      QuestionText4: String,
      Options4: [String],
      QuestionText5: String,
      Options5: [String],
      
    },
    TF: {
      startdate: Date,
    enddate: Date,
      QuestionText1: String,
      Options1: Boolean,
      QuestionText2: String,
      Options2: Boolean,
      QuestionText3: String,
      Options3: Boolean,
      QuestionText4: String,
      Options4: Boolean,
      QuestionText5: String,
      Options5: Boolean,
    },
  },
  {
    collection: "questions",
  }
);

这行得通吗?

// Display list of user surveys
module.exports.displayUserSurveys = (req, res, next) => {
  let id = req.user._id;


  Survey.find({ User: id }, (err, surveyList) => {
    if (err) {
      console.log(err);
      res.end(err);
    } else {
      Survey.aggregate([
        { $match: { User: id }},
        { 
            $lookup : {
                from: "Question",
                localField: "Questions",
                foreignField: "_id",
                as: "questions"
            }
        }
    ]).exec((err, questionList) => {
      if(err) {
        console.log(err);
          res.end(err);
      } else {
        let currentDate = new Date();
              res.render("content/survey/my-surveys", {
                title: "My Surveys",
                page: "my-surveys",
                username: req.user ? req.user.username : "",
                SurveyList: surveyList,
                QuestionList: questionList,
                today: currentDate,
              });
      }
    });
    }
  });
};

标签: javascriptmongodbexpressmongoose

解决方案


如果我正确理解您的问题,我认为您希望有这样的 JOIN(SQL 中的表示):

SELECT *
FROM Surveys
JOIN Questions ON Surveys.Questions = Questions._id
WHERE Surverys.User = { UserID }

这可以在 MongoDB 中使用带有 $lookup 运算符的聚合来实现。

const surveys = await Survey.aggregate([
    { $match: { User: id }},
    { 
        $lookup : {
            from: "questions",
            localField: "Questions",
            foreignField: "_id",
            as: "questions"
        }
    }
]).exec()

console.log(surveys)
// [
//     { Title: "bla", User: "5d8151ec96fb4f0ed5a7a03f", ...,  questions: 
//         [
//             { MC: { ... }, TF: { ... }
//         ] 
//     },
//     { Title: "bla2", User: "5d8151ec96fb4f0ed5a7a03f", ...,  questions: 
//         [
//             { MC: { ... }, TF: { ... }
//         ] 
//     }
// ]

// get the first survey
console.log(surveys[0])

// get the first questionText
console.log(surveys[0].questions[0].MC.QuestionText1)

但作为建议:如果您之间只有一对一的关系,我不会使用两个不同的集合。只需将问题嵌套到调查中即可。


推荐阅读