Starting from version 3.4, we can use the $addFields
aggregation pipeline operator to this without client side processing which is the most efficient way.
db.collection.aggregate(
[
{ "$addFields": { "field2": "$field1" }},
{ "$out": "collection" }
]
)
Prior to version 3.4 we need to iterate the Cursor
object and use $set operator to add the new field with the existing "field1" value. You need to do this using "bulk" operation for maximum efficiency.
MongoDB 3.2 deprecates Bulk() and its associated methods, thus from 3.2 upwards you need to use the bulkWrite method.
var requests = [];
db.collection.find({}, { 'field1': 1 } ).snapshot().forEach(document => {
requests.push( {
'updateOne': {
'filter': { '_id': document._id },
'update': { '$set': { 'field2': document.field1 } }
}
});
if (requests.length === 1000) {
//Execute per 1000 operations and re-init
db.collection.bulkWrite(requests);
requests = [];
}
});
if(requests.length > 0) {
db.collection.bulkWrite(requests);
}
From version 2.6 to 3.0 you can use the Bulk
API.
var bulk = db.collection.initializeUnorderedBulOp();
var count = 0;
db.collection.find({}, { 'field1': 1 }).snapshot().forEach(function(document) {
bulk.find({ '_id': document._id }).updateOne( {
'$set': { 'field2': document.field1 }
});
count++;
if(count%1000 === 0) {
// Excecute per 1000 operations and re-init
bulk.execute();
bulk = db.collection.initializeUnorderedBulkOp();
}
})
// clean up queues
if(count > 0) {
bulk.execute();
}