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);
});
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
nodejs. Using mongodb package from npm
db.collection('ABC').find({url: /helloWorldt/}).toArray((err, docs) => {
docs.forEach(doc => {
let URL = doc.URL.replace('helloWorldt', 'helloWorld');
db.collection('ABC').updateOne({_id: doc._id}, {URL});
});
});
To replace ALL occurrences of the substring in your document use:
db.media.find({mediaContainer:"ContainerS3"}).forEach(function(e,i) {
var find = "//a.n.com";
var re = new RegExp(find, 'g');
e.url=e.url.replace(re,"//b.n.com");
db.media.save(e);
});
The formatting of my comment to the selected answer (@Naveed's answer) has got scrambled - so adding this as an answer. All credit goes to Naveed.
----------------------------------------------------------------------
Just awesome. My case was - I have a field which is an array - so I had to add an extra loop.
My query is:
db.getCollection("profile").find({"photos": {$ne: "" }}).forEach(function(e,i) {
e.photos.forEach(function(url, j) {
url = url.replace("http://a.com", "https://dev.a.com");
e.photos[j] = url;
});
db.getCollection("profile").save(e);
eval(printjson(e));
})
Starting Mongo 4.2
, db.collection.update()
can accept an aggregation pipeline, finally allowing the update of a field based on another field:
// { URL: "www.abc.com/helloWorldt/..." }
// { URL: "www.abc.com/HelloWo/..." }
db.collection.update(
{ URL: { $regex: "/helloWorldt/" } },
[{
$set: { URL: {
$concat: [
{ $arrayElemAt: [ { $split: [ "$URL", "/helloWorldt/" ] }, 0 ] },
"/helloWorld/",
{ $arrayElemAt: [ { $split: [ "$URL", "/helloWorldt/" ] }, 1 ] }
]
}}
}],
{ multi: true }
)
// { URL: "www.abc.com/helloWorld/..." }
// { URL: "www.abc.com/HelloWo/..." }
This is a bit verbose since there isn't a proper string $replace
operator yet.
The first part
{ URL: { $regex: "/helloWorldt/" } }
is the match query, filtering which documents to update (the ones with hello world wrongly spelled).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 which in this case creates/replaces a field. The new value is weirdly computed using a mix of$concat
and$split
by lack of a proper string$replace
operator. Note howURL
is modified directly based on the its own value ($URL
).Don't forget
{ multi: true }
, otherwise only the first matching document will be updated.
Now you can do it!
We can use Mongo script to manipulate data on the fly. It works for me!
I use this script to correct my address data.
Example of current address: "No.12, FIFTH AVENUE,".
I want to remove the last redundant comma, the expected new address ""No.12, FIFTH AVENUE".
var cursor = db.myCollection.find().limit(100);
while (cursor.hasNext()) {
var currentDocument = cursor.next();
var address = currentDocument['address'];
var lastPosition = address.length - 1;
var lastChar = address.charAt(lastPosition);
if (lastChar == ",") {
var newAddress = address.slice(0, lastPosition);
currentDocument['address'] = newAddress;
db.localbizs.update({_id: currentDocument._id}, currentDocument);
}
}
Hope this helps!
Just in case if you are using examples from the answers here and get "Updated 0 existing records" when running your replace script, check whether your client is connected to the primary MongoDB node that allows you to store/write changes.
Using mongodump,bsondump and mongoimport.
Sometimes the mongodb collections can get little complex with nested arrays/objects etc where it would be relatively difficult to build loops around them. My work around is kinda raw but works in most scenarios regardless of complexity of the collection.
1. Export The collection using mongodump into .bson
mongodump --db=<db_name> --collection=<products> --out=data/
2. Convert .bson into .json format using bsondump
bsondump --outFile products.json data/<db_name>/products.bson
3. Replace the strings in the .json file with sed(for linux terminal) or with any other tools
sed -i 's/oldstring/newstring/g' products.json
4. Import back the .json collection with mongoimport with --drop tag where it would remove the collection before importing
mongoimport --db=<db_name> --drop --collection products <products.json
Alternatively you can use --uri for connections in both mongoimport and mongodump
example
mongodump --uri "mongodb://mongoadmin:mystrongpassword@10.148.0.7:27017,10.148.0.8:27017,10.148.0.9:27017/my-dbs?replicaSet=rs0&authSource=admin" --collection=products --out=data/
来源:https://stackoverflow.com/questions/12589792/how-to-replace-substring-in-mongodb-document