How to replace substring in mongodb document

I have a lot of mongodb documents in a collection of the form:

{
....
"URL":"www.abc.com/helloWorldt/..."
.....
}

I want to replace helloWorldt with helloWorld to get:

{
....
"URL":"www.abc.com/helloWorld/..."
.....
}

How can I achieve this for all documents in my collection?


db.media.find({mediaContainer:"ContainerS3"}).forEach(function(e,i) {
    e.url=e.url.replace("//a.n.com","//b.n.com");
    db.media.save(e);
});

Nowadays,

  • starting Mongo 4.2, db.collection.updateMany (alias of db.collection.update) can accept an aggregation pipeline, finally allowing the update of a field based on its own value.
  • starting Mongo 4.4, the new aggregation operator $replaceOne makes it very easy to replace part of a string.
// { URL: "www.abc.com/helloWorldt/..." }
// { URL: "www.abc.com/HelloWo/..." }
db.collection.updateMany(
  { URL: { $regex: /helloWorldt/ } },
  [{
    $set: { URL: {
      $replaceOne: { input: "$URL", find: "helloWorldt", replacement: "helloWorld" }
    }}
  }]
)
// { URL: "www.abc.com/helloWorld/..." }
// { URL: "www.abc.com/HelloWo/..." }
  • The first part ({ URL: { $regex: /helloWorldt/ } }) is the match query, filtering which documents to update (the ones containing "helloWorldt") and is just there to make the query faster.
  • The second part ($set: { URL: {...) is the update aggregation pipeline (note the squared brackets signifying the use of an aggregation pipeline):
    • $set is a new aggregation operator (Mongo 4.2) which in this case replaces the value of a field.
    • The new value is computed with the new $replaceOne operator. Note how URL is modified directly based on the its own value ($URL).

Before Mongo 4.4 and starting Mongo 4.2, due to the lack of a proper string $replace operator, we have to use a bancal mix of $concat and $split:

db.collection.updateMany(
  { URL: { $regex: "/helloWorldt/" } },
  [{
    $set: { URL: {
      $concat: [
        { $arrayElemAt: [ { $split: [ "$URL", "/helloWorldt/" ] }, 0 ] },
        "/helloWorld/",
        { $arrayElemAt: [ { $split: [ "$URL", "/helloWorldt/" ] }, 1 ] }
      ]
    }}
  }]
)