UpTheCreek UpTheCreek - 1 year ago 132
Node.js Question

Iterating over a mongodb cursor serially (waiting for callbacks before moving to next document)

Using mongoskin, I can do a query like this, which will return a cursor:

myCollection.find({}, function(err, resultCursor) {
resultCursor.each(function(err, result) {

}
}


However, I'd like to call some async functions for each document, and only move on to the next item on the cursor after this has called back (similar to the eachSeries structure in the async.js module). E.g:

myCollection.find({}, function(err, resultCursor) {
resultCursor.each(function(err, result) {

externalAsyncFunction(result, function(err) {
//externalAsyncFunction completed - now want to move to next doc
});

}
}


How could I do this?

Thanks

UPDATE:

I don't wan't to use
toArray()
as this is a large batch operation, and the results might not fit in memory in one go.

Answer

If you don't want to load all of the results into memory using toArray, you can iterate using the cursor with something like the following.

myCollection.find({}, function(err, resultCursor) {
  function processItem(err, item) {
    if(item === null) {
      return; // All done!
    }

    externalAsyncFunction(item, function(err) {
      resultCursor.nextObject(processItem);
    });

  }

  resultCursor.nextObject(processItem);
}