6

I have mongodb documents with a field like this:

Image : http://static14.com/p/Inc.5-Black-Sandals-5131-2713231-7-zoom.jpg

How can I replace the zoom part in the string value with some other text in order to get:

Image : http://static14.com/p/Inc.5-Black-Sandals-5131-2713231-7-product2.jpg
0

3 Answers 3

8

You could use mongo's forEach() cursor method to do an atomic update with the $set operator :

db.collection.find({}).snapshot().forEach(function(doc) {
    var updated_url = doc.Image.replace('zoom', 'product2');
    db.collection.update(
        {"_id": doc._id}, 
        { "$set": { "Image": updated_url } }
    );
});

Given a very large collection to update, you could speed up things a little bit with bulkWrite and restructure your update operations to be sent in bulk as:

var ops = [];
db.collection.find({}).snapshot().forEach(function(doc) {
    ops.push({
        "updateOne": {
            "filter": { "_id": doc._id },
            "update": { "$set": { "Image": doc.Image.replace('zoom', 'product2') } }
        }
    });

    if ( ops.length === 500 ) {
        db.collection.bulkWrite(ops);
        ops = [];
    }
})

if ( ops.length > 0 )  
    db.collection.bulkWrite(ops);
Sign up to request clarification or add additional context in comments.

Comments

0
db.myCollection.update({image: 'http://static14.com/p/Inc.5-Black-Sandals-5131-2713231-7-zoom.jpg'}, {$set: {image : 'http://static14.com/p/Inc.5-Black-Sandals-5131-2713231-7-product2.jpg'}})

If you need to do this multiple times to multiple documents, you need to iterate them with a function. See here: MongoDB: Updating documents using data from the same document

2 Comments

there are more than 70000 enteries ur solution wont be possible
It's enough that you wouldn't want to do them by hand as my answer suggests. But the question does not specify how many documents need to be changed
0

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.
// { "Image" : "http://static14.com/p/Inc.5-Black-Sandals-5131-2713231-7-zoom.jpg" }
// { "Image" : "http://static14.com/p/Inc.5-Black-Sandals-5131-2713231-7-boom.jpg" }
db.collection.updateMany(
  { "Image": { $regex: /zoom/ } },
  [{
    $set: { "Image": {
      $replaceOne: { input: "$Image", find: "zoom", replacement: "product2" }
    }}
  }]
)
// { "Image" : "http://static14.com/p/Inc.5-Black-Sandals-5131-2713231-7-product2.jpg" }
// { "Image" : "http://static14.com/p/Inc.5-Black-Sandals-5131-2713231-7-boom.jpg" }
  • The first part ({ "Image": { $regex: /zoom/ } }) is just there to make the query faster by filtering which documents to update (the ones containing "zoom")
  • The second part ($set: { "Image": {...) 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 Image is modified directly based on the its own value ($Image).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.