How to replace substring in mongodb document
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 ofdb.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 howURL
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 ] } ] }} }])
Currently, you can't use the value of a field to update it. So you'll have to iterate through the documents and update each document using a function. There's an example of how you might do that here: MongoDB: Updating documents using data from the same document