【问题标题】:Fetch from multiple, separate, collections with Express and MongoDB使用 Express 和 MongoDB 从多个单独的集合中获取
【发布时间】:2016-05-19 13:48:31
【问题描述】:

我有一个网站,我需要显示我的 Mongo 数据中的一些数据。但是,我的问题是我需要来自两个集合的数据。完全独立且彼此无关的集合。

现在我的个人资料页面的路线中有这个:

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

   mongo.connect(url, function(err, db) {
      var cursor = db.collection('users').find();
      cursor.forEach(function(doc, err) {
         resultArray.push(doc);
      }, function() {
         db.close();
         res.render('profile/index', {users: resultArray});
      });
   });
});

当然,这完全可以正常工作。但是如何让第二个db.collection('colors').find(); 也传递给我的模板?

我确定这是微不足道的事情,我只是没有完全掌握事情,但是是的..我被卡住了..

【问题讨论】:

    标签: node.js mongodb express database


    【解决方案1】:

    使用最适合这种情况的async 库。如果您需要运行多个不依赖于彼此的任务,并且当它们都完成其他操作时,您应该使用 async.parallel() 方法。签名是async.parallel(tasks, callback),其中tasks 是一个函数数组。

    它会立即并行运行所有函数,等待所有函数调用它们的任务回调,最后当所有任务完成时,它会运行回调(最终回调)。

    以下示例演示了如何根据您的用例进行调整:

    router.get('/profile', function(req, res, next) {
        mongo.connect(url, function(err, db) {
            var locals = {};
            var tasks = [
                // Load users
                function(callback) {
                    db.collection('users').find({}).toArray(function(err, users) {
                        if (err) return callback(err);
                        locals.users = users;
                        callback();
                    });
                },
                // Load colors
                function(callback) {
                    db.collection('colors').find({}).toArray(function(err, colors) {
                        if (err) return callback(err);
                        locals.colors = colors;
                        callback();
                    });
                }
            ];
    
            async.parallel(tasks, function(err) { //This function gets called after the two tasks have called their "task callbacks"
                if (err) return next(err); //If an error occurred, let express handle it by calling the `next` function
                // Here `locals` will be an object with `users` and `colors` keys
                // Example: `locals = {users: [...], colors: [...]}`
                db.close();
                res.render('profile/index', locals);
            });
        });
    });
    

    【讨论】:

    • 这很有趣,而且绝对是一种更合适的方式。我试试看!
    • 这是正确的方法,因为它可以更好地处理异步方法。在另一个答案中,您一定会得到不正确的结果,因为 resultsArray 是同步填充的。更好的方法是使用Promises,因为它们在处理异步任务时提供了更大的灵活性,我建议任何人在使用不同的解决方案之前考虑使用它们。
    • promise 的一般概念是它们是未来值的容器。当一个 Promise 接收到这个值(它被解析)或当它被取消(被拒绝)时,它会通知所有想要访问这个值的“侦听器”。
    • 你是男人!谢谢!
    【解决方案2】:

    试试这个代码:

    router.get('/profile', function(req, res,next) {
       var resultArray = {
                          users : [],
                          colors : []
                         };
    
       mongo.connect(url, function(err, db) {
          var cursor = db.collection('users').find();
          cursor.forEach(function(doc, err) {
             resultArray.users.push(doc);
          }
          var colors = db.collection('colors').find();
          colors.forEach(function(doc,err){
              resultArray.colors.push(doc);
           }, function() {
             db.close();
             res.render('profile/index', {users: resultArray.users, colors: resultArray.colors});
          });
       });
    });
    

    没有时间检查,但我很确定它会起作用。

    【讨论】:

      猜你喜欢
      • 2013-08-20
      • 2017-04-03
      • 2020-05-13
      • 2019-11-25
      • 1970-01-01
      • 1970-01-01
      • 2014-07-29
      • 2014-01-20
      • 1970-01-01
      相关资源
      最近更新 更多