2016-05-19 6 views
2

Mongoデータからいくつかのデータを表示する必要があるサイトがあります。私の問題は、しかし、私は2つのコレクションからのデータが必要です。コレクションは完全に別物であり、お互いに関係がありません。ExpressとMongoDBで複数の別々のコレクションから取得する

は、今私は私のプロフィールページのための私のルートでこれを持っている:

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}); 
     }); 
    }); 
}); 

そして、これは、もちろん、完全に正常に動作します。しかし、私はどのように私のテンプレートにも渡される2番目のdb.collection('colors').find();を取得するのですか?

答えて

6

このシナリオに最も適した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); 
     }); 
    }); 
}); 
+0

これは非常に面白く、間違いなくより適切な方法のようです。私はそれをショットを与えるよ! –

+1

非同期メソッドをはるかに上手く処理するので、正しい方法です。もう一つの答えでは、 'resultsArray'が同期して生成されるので、間違った結果を得ることになります。はるかに優れたアプローチは、[** Promises **](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)を使用することです。非同期タスクを扱うことができます。異なるソリューションに頼る前に、誰でもそれらの使用を検討することをお勧めします。 – chridam

+0

約束の一般的な概念は、将来の価値のためのコンテナであるということです。プロミスが値を受け取ると(解決される)、取り消されたとき(拒否された場合)、この値にアクセスするすべての「リスナー」に通知されます。 – chridam

0

このコードを試してみてください..私はそれは些細なものだと確信している、と私はちょうど非常に物事の完全な把握を持っていない、しかし、ええ..私はこだわっている:

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}); 
     }); 
    }); 
}); 

didnのそれをチェックする時間がありますが、私はそれがうまくいくと確信しています。

+0

完璧に働いたこと。どうもありがとうございました! –

関連する問題