0

我有一個查詢可以獲取排行榜的前5位用戶。在robomongo這個查詢工作正常。將兩個查詢結果傳遞給響應

當我這樣做

var leaderboard = User.find({points: {$exists: true}}, { 
    "firstname": 1, 
    "lastname": 1, 
    "points": 1 
}).sort({points : -1}).limit(5) 
console.log('leaderboard'); 

我得到了很多無意義的JSON與[對象]幾乎無處不在。

我將如何執行這個查詢與貓鼬用+表示這樣我就可以通過該視圖的

firstname, lastname, points 

,所以我可以循環它通過在視圖中的數組?

我完整的代碼是

app.get('/dashboard', function(req, res){ 

    if (req.user) { 
    // logged in 

    User.find({}, function(err, docs) { 
     // console.log(docs); 
    }); 

    // Get total points after submit 
    var leaderboard = User.find({points: {$exists: true}}, { 
     "firstname": 1, 
     "lastname": 1, 
     "points": 1 
    }).sort({points : -1}).limit(5).toArray(); 
    console.log(leaderboard); 

    User.find({ 
     points: { 
      $exists: true 
     } 
    }, function(err, docs) { 
     if(err){ 
      console.log(err); 
      //do error handling 
     } 
     //if no error, get the count and render it 
     var count = 0; 
     for (var i = 0; i < docs.length; i++) { 
      count += docs[i].points; 
     } 
     var totalpoints = count; 

     res.render('dashboard', { 
     title: 'Dashboard', 
     user: req.user, 
     totalpoints: totalpoints 
     }); 
    }); 

    } else { 
    // not logged in 
    return res.redirect('/login'); 
    } 

}); 
+0

就像你在後面的代碼做,你只能得到的結果在回調中。由於查詢尚未執行,「無意義的[Object]」實際上就是「遊標」定義。 –

+0

是可以讓它在相同的回調查詢? – ServerSideSkittles

回答

1

所以,你真的只在這裏返回一個指針,而不是執行查詢。你當然可以總是嵌套查詢,但你可以更好一些,並使用async.waterfall來避免縮進混亂。

此外,我會使用.aggregate()而不是循環所有的文件只是爲了得到一個總數。如在這裏的例子做

app.get('/dashboard', function(req, res){ 

    if (req.user) { 
    // logged in 

    async.waterfall(
     [ 
     function(callback) { 
      User.find(
      { "points": { "$exists": true } }, 
      { 
       "firstname": 1, 
       "lastname": 1, 
       "points": 1 
      } 
     ).sort({points : -1}).limit(5).exec(callback); 
     }, 
     function(leaderboard,callback) { 
      User.aggregate(
      [ 
       { "$match": { "points": { "$exists": true } }}, 
       { "$group": { 
       "_id": null, 
       "totalpoints": { "$sum": "$points" } 
       }} 
      ], 
      function(err,result) { 
       callback(err,result,leaderboard) 
      } 
     ); 
     } 
     ], 
     function(err,result,leaderboard) { 
     if (err) { 
      console.log(err); 
      //do error handling 
     } else { 
      res.render('dashboard', { 
      title: 'Dashboard', 
      user: req.user, 
      totalpoints: result[0].totalpoints, 
      leaderboard: leaderboard 
      }); 
     } 
     } 
    ); 
    } else { 
    // not logged in 
    return res.redirect('/login'); 
    } 

}); 

所以,你得到你的leaderboard結果,只是把它的響應,許多:和貓鼬結果自動轉換成一個陣列,所以.toArray()這裏不需要。

另一種方法是使用async.parallel,因爲您不需要在第二個查詢中輸出第一個查詢。在這種情況下,兩個查詢的結果都會在最後發送到回調函數,就像上面那樣。再次,您只需在最終答覆中使用結果。

app.get('/dashboard', function(req, res){ 

    if (req.user) { 
    // logged in 

    async.parallel(
     { 
     "leaderboard": function(callback) { 
      User.find(
      { "points": { "$exists": true } }, 
      { 
       "firstname": 1, 
       "lastname": 1, 
       "points": 1 
      } 
     ).sort({points : -1}).limit(5).exec(callback); 
     }, 
     "totalpoints":function(callback) { 
      User.aggregate(
      [ 
       { "$match": { "points": { "$exists": true } }}, 
       { "$group": { 
       "_id": null, 
       "totalpoints": { "$sum": "$points" } 
       }} 
      ], 
      function(err,result) { 
       callback(err,result[0].totalpoints) 
      } 
     ); 
     } 
     }, 
     function(err,results) { 
     if (err) { 
      console.log(err); 
      //do error handling 
     } else { 
      res.render('dashboard', { 
      title: 'Dashboard', 
      user: req.user, 
      totalpoints: results.totalpoints, 
      leaderboard: results.leaderboard 
      }); 
     } 
     } 
    ); 
    } else { 
    // not logged in 
    return res.redirect('/login'); 
    } 

}); 
+0

似乎我有很多需要閱讀的mongodb實踐。感謝這樣一個詳細的解釋,我是mongo的新手,這對我有很大幫助! – ServerSideSkittles

+1

@ServerSideSkittles你一定要閱讀[聚合框架](http://docs.mongodb.org/manual/core/aggregation-pipeline/),因爲這是一個數據庫,你通常不想在代碼中迭代文檔。還使用'async.parallel'添加了一個列表,它確實應該更適合這個目的。 –

相關問題