猫鼬内的嵌套查询

时间:2018-11-01 12:09:41

标签: node.js mongoose

我有一个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

因为我假设在输出console.log("class room name: + roomList[i].name)

之后立即执行Students.find

但是结果是所有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

在这种情况下,如何执行正确的嵌套查询?

2 个答案:

答案 0 :(得分:1)

  

猫鼬查询不是承诺。他们有一个.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

答案 1 :(得分: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});
      });
  }
});