codemonkey
codemonkey

Reputation: 7905

How to update part of a string of mongodb documents?

My collection looks like this:

  {
    "_id": 1,
    "integration_id": 222,
    "log_file": "/var/www/html/logs/posts/10608.log",
    "active": true,
    
  },
  {
    "_id": 2,
    "integration_id": 344,
    "log_file": "/var/www/html/logs/posts/10223.log",
    "active": true,
    
  },
  {
    "_id": 3,
    "integration_id": 124,
    "log_file": "/var/www/html/logs/posts/19178.log",
    "active": true,
    
  },
  {
    "_id": 4,
    "integration_id": 872,
    "active": true,
    
  }

I want to update all documents where log_file is present, but I want to update only the path to the log file. For example /var/www/html/logs/posts/10608.log should become /new/path/to/log/10608.log

The end result should be:

{
    "_id": 1,
    "integration_id": 222,
    "log_file": "/new/path/to/log/10608.log",
    "active": true,

  },
  {
    "_id": 2,
    "integration_id": 344,
    "log_file": "/new/path/to/log/10223.log",
    "active": true,
  }
...
...

I tried running this command from the shell:

db.collection.find({
    log_file: {
        "$ne": null
    }
}).forEach(function(d, i) {
    d.log_file.replace("/var/www/html/logs/posts/", "/new/path/to/log/");
    db.collection.save(d);
})

But nothing happens. No errors or any kind of output and nothing is updated. Can someone help?

For what it's worth, I'm using MongoDB Atlas. Just wanted to put that out there in case someone knows of any limitations on these kinds of operations they impose.

Upvotes: 0

Views: 72

Answers (2)

Pinky Promise
Pinky Promise

Reputation: 223

If you would like to use MongoDB aggregation. You can do something like this.

    db.collection.aggregate([
      {
        "$addFields": {
          log_file: {
            $replaceOne: {
              input: "$log_file",
              find: "/var/www/html/logs/posts/",
              replacement: "/new/path/to/log/"
            }
          }
        }
      }
    ])

You can check Playground here.

Upvotes: 1

Christian Fritz
Christian Fritz

Reputation: 21364

I would use $exists, also you need to set log_file to the result of the replace (replace does not replace in place):

db.collection.find({
    log_file: {$exists: true}
}).forEach(function(d, i) {
    d.log_file = d.log_file.replace("/var/www/html/logs/posts/", "/new/path/to/log/");
    db.collection.save(d);
})

Upvotes: 1

Related Questions