Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MongoDB: Update a string field in all documents

I have a MongoDB database with many documents in a collection. Each of those articles has a field called myField containing a string.

Is it possible for me to run a bulk update on all documents in the collection, modifying the value of myField for each document?

In my case I just want to strip off a trailing ".html" from each of the fields. I'm using node.js to interact with Mongo in my application but I'd prefer to be able to run a single command on the mongo command prompt to do this update if that's possible.

like image 202
TW80000 Avatar asked Dec 04 '25 17:12

TW80000


2 Answers

Yest it possible to update mongoDB document information from command prompt using mongo.

say script file name migration.js and go to this file directory and open command prompt and run this command.

mongo localhost/dbName migration.js

and migration.js code like:

print('Please wait it may will take some time to complete migration');
print('....');

db.collectionName.find().forEach( function(doc) {

    if(!doc._id) {
        print('No doc found');
        return;
    }
    // if need can apply logic to update myField

    db.collectionName.update({_id: doc._id}, {$set: {myField: "newVale"}});
});

print('Migration has been completed :)');
like image 88
Shaishab Roy Avatar answered Dec 06 '25 08:12

Shaishab Roy


Consider using the bulkWrite API to leverage the updates as it handles this much better and more efficient than doing the updates within a loop i.e. sending each update request with each iteration may be slow with large datasets.

The bulkWrite API sends the writes to the server in batches of say 500 which gives you a better performance as you are not sending every request to the server, just once in every 500 requests.

For bulk operations MongoDB imposes a default internal limit of 1000 operations per batch and so a choice of 500 documents will be good in the sense that you have some control over the batch size rather than let MongoDB impose the default, i.e. for larger operations in the magnitude of > 1000 documents.

Take the following example:

var bulkUpdateOps = [], // create an array to hold the update operations
    counter = 0, // counter to control the batch sizes
    rgx = /\.(html)$/i, // regex for querying and updating the field
    cursor = db.collection.find({ "myField": rgx }); // cursor for iterating

cursor.snapshot().forEach(function(doc) {
    var updatedField = doc.myField.replace(rgx, ''); // update field
    bulkUpdateOps.push({ // queue the update operations to an array
        "updateOne": {
            "filter": { 
                "_id": doc._id, 
                "myField": { "$ne": updatedField } 
            },
            "update": { "$set": { "myField": updatedField } }
        }
    });
    counter++;

    if (counter % 500 == 0) { // send the update ops in bulk
        db.collection.bulkWrite(bulkUpdateOps);
        bulkUpdateOps = []; // reset the array
    }
})

if (counter % 500 != 0) { // clean up remaining operations in the queue
    db.collection.bulkWrite(bulkUpdateOps)
}
like image 26
chridam Avatar answered Dec 06 '25 07:12

chridam