【问题标题】:nested query inside mongoose猫鼬内的嵌套查询
【发布时间】:2019-04-05 15:51:53
【问题描述】:

我有一个 Student.find 查询,它在 Room.find 查询中运行,如下所示:

Room.find({ schoolID:  mongoose.mongo.ObjectId(user.schoolID) }).sort({'level':'ascending','name':'ascending'}).then(function (roomList) {
  if (!roomList){
    console.log("no class room found")
  }else{
    console.log("class room found: " + roomList.length)
    var studentList = []
    for (var i = 0; i < roomList.length; i++){
      console.log(i)
      console.log("class room id: " + roomList[i]._id)
      console.log("class room name: " + roomList[i].name)
      Students.find({ schoolID:  mongoose.mongo.ObjectId(user.schoolID), classRoomID:  mongoose.mongo.ObjectId(roomList[i]._id) }).sort({'firstName':'ascending'}).then(function (data) {
        if (!data){
          console.log("no data found")
          return res.status(200).send({success: true, msg: 'No data found.'});
        }else{
          console.log("214 ada data: " + data.length)
          studentList[i] = data
          console.log("studentList " + i)
          console.log(studentList[i])
        }
      });
    }
    res.json({success: true, token: 'JWT ' + token, id: user._id, user: user, classRoom: roomList, students: studentList});    
  }
});

在数据库中,有 6 个教室,每个班级的学生人数不同。在 console.log 中,我期待看到类似的内容:

class room id: 01
class room name: my first class
studentList 0:
list of students from first class

class room id: 02
class room name: my second class
studentList 1:
list of students from 2nd class

class room id: 03
class room name: my third class
studentList 2:
list of students from 3rd class

因为我假设 Student.find 将在我输出 console.log("class room name: + roomList[i].name) 后立即执行

但原来所有的console.log("class room id") 和console.log("class room name") 都是先打印出来的,然后好像只有Students.find 被执行了,因为我的输出是什么像这样:

class room id: 01
class room name: my first class
class room id: 02
class room name: my second class
class room id: 03
class room name: my third class
class room id: 04
class room name: my fourth class
class room id: 05
class room name: my fifth class
class room id: 06
class room name: my six class

list of students
list of students
list of students
list of students
list of students
list of students

如果是这种情况,我该如何进行正确的嵌套查询?

【问题讨论】:

    标签: node.js mongoose


    【解决方案1】:
    Room.find({ schoolID:  mongoose.mongo.ObjectId(user.schoolID) }).sort({'level':'ascending','name':'ascending'}).then(function (roomList) {
      if (!roomList){
        console.log("no class room found")
      }else{
        console.log("class room found: " + roomList.length)
        var promsies = [];
        if (roomList.length) return res.status(200).send({success: true, msg: 'No data found.'});
        for (var i = 0; i < roomList.length; i++){
          console.log(i)
          console.log("class room id: " + roomList[i]._id)
          console.log("class room name: " + roomList[i].name)
          promsies.push(Students.find({ schoolID:  mongoose.mongo.ObjectId(user.schoolID), classRoomID:  mongoose.mongo.ObjectId(roomList[i]._id) }).sort({'firstName':'ascending'}));
        }
        Promise.all(promsies).then(function (studentList) {
            res.json({success: true, token: 'JWT ' + token, id: user._id, user: user, classRoom: roomList, students: studentList});
          });
      }
    });
    

    【讨论】:

      【解决方案2】:

      Mongoose 查询不是承诺。他们有一个用于 co 的 .then() 函数 和 async/await 作为一种方便。如果你需要一个成熟的承诺, 使用 .exec() 函数。

      试试:

      Room.find({
        schoolID: mongoose.mongo.ObjectId(user.schoolID)
      }).sort({
        'level': 'ascending',
        'name': 'ascending'
      }).exec().then(function(roomList) {
        if (!roomList) {
          console.log("no class room found")
        } else {
          console.log("class room found: " + roomList.length)
          var studentList = []
          for (var i = 0; i < roomList.length; i++) {
            console.log(i)
            console.log("class room id: " + roomList[i]._id)
            console.log("class room name: " + roomList[i].name)
            Students.find({
              schoolID: mongoose.mongo.ObjectId(user.schoolID),
              classRoomID: mongoose.mongo.ObjectId(roomList[i]._id)
            }).sort({
              'firstName': 'ascending'
            }).exec().then(function(data) {
              if (!data) {
                console.log("no data found")
                return res.status(200).send({
                  success: true,
                  msg: 'No data found.'
                });
              } else {
                console.log("214 ada data: " + data.length)
                studentList[i] = data
                console.log("studentList " + i)
                console.log(studentList[i])
              }
            });
          }
          res.json({
            success: true,
            token: 'JWT ' + token,
            id: user._id,
            user: user,
            classRoom: roomList,
            students: studentList
          });
        }
      });
      

      您遇到的另一个问题是您正在尝试使用异步进行 for 循环。它不能那样工作......(for循环不会等待并且会继续运行)要么使用Promise.All,要么使用among these lines

      【讨论】:

      • 谢谢,但console.log("studentList " + i) 将始终显示studentList 6console.log(i) 正下方的 for (var i = 0; i &lt; roomList.length; i++) 行将正确显示 0 直到 5 (因为有 6 个类),但在 Students.find() 下的 i 似乎只有 6 个。我的假设是因为学生.find() 将始终仅在 for 循环完成后执行/完成执行......它应该这样吗?
      • 我需要的是每个Students.find()在检索到roomList id和name后完成执行,这样我就可以将Students.find()的结果传递给每个roomList[i]。学生(类似的)
      • 您不能将 for 循环与异步一起使用。我用一个链接更新了答案供您参考。
      • 谢谢!我会答应一切的。您的回答帮助我更多地了解问题和解决方案,但我才意识到黄乔森已经给出了关于如何使用 Promise.all 的答案。 +2 为您提供帮助!
      猜你喜欢
      • 2021-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-08
      • 2015-04-10
      • 2019-04-06
      • 1970-01-01
      相关资源
      最近更新 更多