1

I have a collection called 'content' includs a big number of documents like this

{"_id":"5e01043e9fde7f33b8133b2d",
"name":"home",
"documentTypeId":"5df01430600e2258382ffb9c",
"parentContnetId":"",
"active":true,
"published":false,
"Url":"/home",
"dataTypes":[],
"__v":0},

{"_id":"5e01045e9fde7f33b8133b2e",
"name":"subhome",
"documentTypeId":"5df01430600e2258382ffb9c",
"parentContnetId":"",
"active":true,
"published":false,
"Url":"/home/subhome",
"dataTypes":[],
"__v":0},

{"_id":"5e01045e9fde7f33b8133b2d",
"name":"subsubhome",
"documentTypeId":"5df01430600e2258382ffb9c",
"parentContnetId":"",
"active":true,
"published":false,
"Url":"/home/subhome/subsubhome",
"dataTypes":[],
"__v":0},

{"_id":"5e01045e9fde7f33b8133b2a",
"name":"subhome2",
"documentTypeId":"5df01430600e2258382ffb9c",
"parentContnetId":"",
"active":true,
"published":false,
"Url":"/home/subhome2",
"dataTypes":[],
"__v":0},

{"_id":"5e01045e9fde7f33b8133b2b",
"name":"subsubhome",
"documentTypeId":"5df01430600e2258382ffb9c",
"parentContnetId":"",
"active":true,
"published":false,
"Url":"/home/subhome2/subsubhome",
"dataTypes":[],
"__v":0}

I want to update the 'Url' field for all of them so I want to replace each '/home' with '/start'. I don't want to get all documents and then update them in node js and after that save each document individually. is there any way to update them throw MongoDB or mongoose will be better without using MongoDB shell, I mean dynamically ?

1 Answers1

0

I don't want to get all documents and then update them in node js and after that save each document individually

Why not? Seems like the fastest way to do it to me. Presuming that the URL substitution needs to happen on every document any operation you do to update it will eventually require you to save every document you modified.

db.content.find().forEach(function(e) {
    e.Url = e.Url.replace("/home","/start");
    db.content.save(e);
});

Be careful with the replacement - what would happen if a URL had /home twice?

If you're truly opposed to doing find and update over the entire collection, this answer provides an overview of how to do it with the aggregation pipeline by splitting the string up into separate fields. Your mileage may vary

jakemingolla
  • 1,613
  • 1
  • 10
  • 13
  • thank you for your reply, I don't want that because I have more than 1000 documents inside that collection and this will take time and maybe the collection will grow in future – Ahmad Osman Dec 23 '19 at 19:35
  • You will still be operating on each result one at a time through the cursor returned from the find operation. I was also presuming that this would be a one-off task that would be combined with a fix-forward elsewhere such that future record would have the correct Url property. – jakemingolla Dec 23 '19 at 19:52
  • this is doable in SQL but I think MongoDB should support such as thing. – Ahmad Osman Dec 23 '19 at 19:57
  • The document structure of Mongo records has downsides to go along with its free-form update policy. And as for performance, I would expect this query to finish near instantaneously on a collection of just a few thousand documents. – jakemingolla Dec 23 '19 at 20:00
  • I will try the solution in the link that you sent, it seems what I want – Ahmad Osman Dec 23 '19 at 20:00
  • you were right, replace not gonna help because it will replace all '/home' in the Url . I need to find another solution for that , maybe changing the Url to an array or add another property refers to the level (index) of the url part – Ahmad Osman Dec 23 '19 at 22:50