nodejs,mongodb - 如何操作来自多个查询的数据?

时间:2011-01-10 02:47:52

标签: javascript mongodb node.js

我一般都是JS的新手,但我试图从MongoDB中查询一些数据。基本上,我的第一个查询检索具有指定会话ID的会话的信息。第二个查询对位于指定位置附近的文档执行简单的geospacial查询。

我正在使用mongodb-native javascript驱动程序。所有这些查询方法都在回调中返回结果,因此它们是非阻塞的。这是我烦恼的根源。我需要做的是检索第二个查询的结果,并创建一个包含所有返回文档的sessionIds数组。然后我将把它们传递给一个函数。但是,我无法生成此数组并在回调之外的任何地方使用它。

有没有人知道如何正确地做到这一点?

db.collection('sessions', function(err, collection) {
  collection.findOne({'sessionId': client.sessionId}, function(err, result) {
    collection.find({'geolocation': {$near: [result.geolocation.latitude, result.geolocation.longitude]}}, function(err, cursor) {
      cursor.toArray(function(err, item) {

      console.log(item);
    });
  });
});

2 个答案:

答案 0 :(得分:6)

函数是javascript上唯一“封闭”范围的东西。

这意味着内部回调函数中的变量项在外部作用域中不可访问。

您可以在外部范围中定义变量,以便所有内部变量都可以看到:

function getItems(callback) {
  var items;

  function doSomething() {
    console.log(items);
    callback(items);
  }

  db.collection('sessions', function(err, collection) {
    collection.findOne({'sessionId': client.sessionId}, function(err, result) {
      collection.find({'geolocation': {$near: [result.geolocation.latitude, result.geolocation.longitude]}}, function(err, cursor) {
        cursor.toArray(function(err, docs) {
          items = docs;
          doSomething();
         });
       });
     });
   });
}

答案 1 :(得分:0)

Node.js是异步的,因此应编写代码以匹配它。

我发现这个模型很有用。每个嵌套的回调混乱都包含在辅助函数中,该函数使用错误代码和结果调用参数callback'next'。

function getSessionIds( sessionId, next ) {
    db.collection('sessions', function(err, collection) {
      if (err) return next(err);
      collection.findOne({sessionId: sessionId}, function(err, doc) {
          if (err) return next(err);
          if (!doc) return next(false);
          collection.find({geolocation: {$near: [doc.geolocation.latitude, result.geolocation.longitude]}}.toArray(function(err, items) {
              return next(err, items);
          });
      });
    });
}

然后在您的通话代码中

getSessionIds( someid, _has_items);
function _has_items(err, items) {
   if( err ) // failed, do something
   console.log(items);
}