I have a huge collection of documents in my DB, i'm wondering how can i run through all the document and update them, each document should get a different value which this value will be taken using some function that i've built. Lets say that my collection name is: tstCollection , and i have 10 docs inside.
The answer depends on the driver you're using. All MongoDB drivers I know have cursor.forEach()
implemented one way or another.
Here are some examples:
collection.find(query).each(function(err, doc) {
// handle
});
db.collection.find(query).forEach(function(err, doc) {
// handle
});
collection.find(query, { stream: true })
.each(function(doc){
// handle doc
})
.error(function(err){
// handle error
})
.success(function(){
// final callback
});
collection.find(query).stream()
.on('data', function(doc){
// handle doc
})
.on('error', function(err){
// handle error
})
.on('end', function(){
// final callback
});
.forEach
callbackThe only problem with updating documents inside of .forEach
callback is that you have no idea when all documents are updated.
To solve this problem you should use some asynchronous control flow solution. Here are some options:
Here is an example of using async
, using its [queue
feature][8]:
var q = async.queue(function (doc, callback) {
// code for your update
collection.update({
_id: doc._id
}, {
$set: {hi: 'there'}
}, {
w: 1
}, callback);
}, Infinity);
var cursor = collection.find(query);
cursor.each(function(err, doc) {
if (err) throw err;
id (doc) q.push(doc); // dispatching doc to async.queue
});
q.drain = function() {
if (cursor.isClosed()) {
console.log('all items have been processed');
db.close();
}
}