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'添加了一个列表,它确实应该更适合这个目的。 –

相关问题