MongoDB: Find and replace string

I am trying to find an effective way for searching and replacing a string across a whole collection. Background is to replace all base URLs contained in a specific field with a new base URL.

According to the MongoDB NodeDriver docs, this should be possible with updateMany():

const rawCollection = myCollection.rawCollection();
rawCollection.updateMany({}, [
      {
        $set: {
          url: { $replaceOne: { input: '$url', find: oldUrl, replacement: newUrl } }
        }
      }
    ]);

However, the driver complains that it doesn’t understand $replaceOne. What is the correct way to do it in Meteor?

I know I could use a bulk operation and iterate over the collection manually, but I’d like to avoid this.

As far as I know $replaceOne is a pipeline operator to be used in aggregations only, and can’t be used in Collection.update.

According to the docs, it should be possible since 4.4, if you use the MongoDB driver (rawCollection) directly and call updateMany. This method supports passing in an aggregation pipeline.

1 Like

Just realized that my Meteor version 1.10.2 did not support MongoDB 4.4 yet, so that’s the reason why it’s not working in my dev environment. Thanks @peterfkruger for pointing me to this!

Still wondering if there’s another way to do collection-wide text replacements in MongoDB?

2 Likes

$split the string by the old url and $concat with the new url

Sounds interesting. How does this actually work? I could only see $split as part of the aggregation pipeline docs, but this would only work if my server was on a more recent Meteor version where updateMany supports aggregations (MongoDB 4.4+). And for this version, I could also use replaceOne. Maybe I missed something?

updateMany aggregation is available starting 4.2