MongoDB update. Trying to set one field from a property of another

Starting Mongo 4.2, db.collection.update() can accept an aggregation pipeline, finally allowing the update/creation of a field based on another field:

// { "_id" : ObjectId("5e84c..."), "field1" : 12, "field2" : "world" }
db.collection.update(
  { "_id" : ObjectId("5e84c...") },
  [{ $set: { field1: { $strLenCP: "$field2" } } }]
)
// { "_id" : ObjectId("5e84c..."), "field1" : 5, "field2" : "world" }
  • The first part {} is the match query, filtering which documents to update.

  • The second part [{ $set: { field1: { $strLenCP: "$field2" } } }] is the update aggregation pipeline (note the squared brackets signifying the use of an aggregation pipeline). $set is a new aggregation operator and an alias for $addFields. Any aggregation operator can be used within the $set stage; in our case $strLenCP which provides the length of field2.


Try the following code:

db.collection.find(your_querry).forEach(function(doc) {
  doc.field1 = doc.field2.length;
  db.collection.save(doc);
});

You can use your_querry to select only part of the original collection do perform an update. If you want to process an entire collection, use your_querry = {}.

If you want all operations to be atomic, use update instead of save:

db.collection.find( your_querry, { field2: 1 } ).forEach(function(doc) {
  db.collection.update({ _id: doc._id },{ $set: { field1: doc.field2.length } } );
});

Tags:

Mongodb