Express JS MongoDB forEach find

时间:2017-05-22 20:26:22

标签: node.js mongodb express

我有一个大问题。 我想迭代收集结果集,并且对于每个集合,我想找到一个结果。

这看起来像这样:

router.get('/', function(req, res) {
    var floors = [];
    var rooms = [];

    req.db.collection('floors').find().sort({_id: 1}).forEach(function(floor) {
        floors.push(floor);
    });

    req.db.collection('rooms').find().sort({_id: 1}).forEach(function(room) {
        req.db.collection('floors').findOne({_id: new ObjectID(room.floorId)}, function(error, floor) {
            room.floor = floor;
            rooms.push(room);
        });
    });

    res.render('rooms', { floors: floors, rooms: rooms });
});

问题是页面将在迭代完成之前呈现。 我试图使用异步和承诺,但我没有让它运行。

1 个答案:

答案 0 :(得分:0)

基本上,您必须等到所有查询完成后再发送渲染结果。不幸的是,你没有使用承诺,所以这会有点混乱。

看起来您正在使用本机客户端,并且根据文档,在所有迭代完成后会调用第二个回调函数 http://mongodb.github.io/node-mongodb-native/2.2/api/Cursor.html#forEach

router.get('/', function(req, res, next) {
  var floors = [];
  var rooms = [];

  function done(err){
    if(err) {
      return next(err);
    }
    res.render('rooms', { floors: floors, rooms: rooms });
  }

  function getRooms(err){
    if(err){
      return next(err);
    }
    req.db.collection('rooms').find().sort({_id: 1}).forEach(function(room) {
      // you already have all the floors, no need to hit the db again
      floors.find(floor => floor._id === room.floorId); // not sure about this 100% as _id could be an object
    }, done);
  }

  req.db.collection('floors').find().sort({_id: 1}).forEach(function(floor) {
    floors.push(floor);
  }, getRooms);

});

需要注意的是,当数据库增长时,此请求会变得非常繁重。