admin管理员组

文章数量:1025457

I'm new to JS in general, but I am trying to query some data from MongoDB. Basically, my first query retrieves information for the session with the specified session id. The second query does a simple geospacial query for documents with a location near the specified location.

I'm using the mongodb-native javascript driver. All of these query methods return their results in callbacks, so they're non-blocking. This is the root of my troubles. What I'm needing to do is retrieve the results of the second query, and create an Array of sessionIds of all the returned documents. Then I'm going to pass those to a function later. But, I can't generate this array and use it anywhere outside the callback.

Does anyone have any idea how to properly do this?

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

I'm new to JS in general, but I am trying to query some data from MongoDB. Basically, my first query retrieves information for the session with the specified session id. The second query does a simple geospacial query for documents with a location near the specified location.

I'm using the mongodb-native javascript driver. All of these query methods return their results in callbacks, so they're non-blocking. This is the root of my troubles. What I'm needing to do is retrieve the results of the second query, and create an Array of sessionIds of all the returned documents. Then I'm going to pass those to a function later. But, I can't generate this array and use it anywhere outside the callback.

Does anyone have any idea how to properly do this?

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);
    });
  });
});
Share Improve this question edited Jan 10, 2011 at 16:57 James Gregory 14.2k2 gold badges45 silver badges60 bronze badges asked Jan 10, 2011 at 2:47 RyanRyan 7,95711 gold badges66 silver badges119 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 6

Functions are the only thing on javascript that "enclose" scope.

This means that the variable items in your inner callback function are not accessible on the outer scope.

You can define a variable in the outer scope so it will be visible to all the inner ones:

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

Node.js is asynchronous, so your code should be written to match it.

I've found this model useful. Each nested callback jumble is wrapped in helper function that calls the argument callback 'next' with error code and result.

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

Then in your calling code

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

I'm new to JS in general, but I am trying to query some data from MongoDB. Basically, my first query retrieves information for the session with the specified session id. The second query does a simple geospacial query for documents with a location near the specified location.

I'm using the mongodb-native javascript driver. All of these query methods return their results in callbacks, so they're non-blocking. This is the root of my troubles. What I'm needing to do is retrieve the results of the second query, and create an Array of sessionIds of all the returned documents. Then I'm going to pass those to a function later. But, I can't generate this array and use it anywhere outside the callback.

Does anyone have any idea how to properly do this?

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

I'm new to JS in general, but I am trying to query some data from MongoDB. Basically, my first query retrieves information for the session with the specified session id. The second query does a simple geospacial query for documents with a location near the specified location.

I'm using the mongodb-native javascript driver. All of these query methods return their results in callbacks, so they're non-blocking. This is the root of my troubles. What I'm needing to do is retrieve the results of the second query, and create an Array of sessionIds of all the returned documents. Then I'm going to pass those to a function later. But, I can't generate this array and use it anywhere outside the callback.

Does anyone have any idea how to properly do this?

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);
    });
  });
});
Share Improve this question edited Jan 10, 2011 at 16:57 James Gregory 14.2k2 gold badges45 silver badges60 bronze badges asked Jan 10, 2011 at 2:47 RyanRyan 7,95711 gold badges66 silver badges119 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 6

Functions are the only thing on javascript that "enclose" scope.

This means that the variable items in your inner callback function are not accessible on the outer scope.

You can define a variable in the outer scope so it will be visible to all the inner ones:

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

Node.js is asynchronous, so your code should be written to match it.

I've found this model useful. Each nested callback jumble is wrapped in helper function that calls the argument callback 'next' with error code and result.

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

Then in your calling code

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

本文标签: javascriptNodejsmongodbHow do I operate on data from multiple queriesStack Overflow