How to update _id of a single MongoDB document?

I want to update the _id field of one document. I know this is not a good practice. But for some technical reason, I need to update it. If I try to update it, I get:

 > db.clients.update({ _id: ObjectId("123")}, { $set: { _id: ObjectId("456")}}) Performing an update on the path '_id' would modify the immutable field '_id' 

And the update is not done. How can I update it?

+119
mongodb
Oct 25 '10 at 8:19
source share
4 answers

You cannot update it. You will need to save the document with the new _id and then delete the old document.

 // store the document in a variable doc = db.clients.findOne({_id: ObjectId("4cc45467c55f4d2d2a000002")}) // set a new _id on the document doc._id = ObjectId("4c8a331bda76c559ef000004") // insert the document, using the new _id db.clients.insert(doc) // remove the document with the old _id db.clients.remove({_id: ObjectId("4cc45467c55f4d2d2a000002")}) 
+196
Oct 25 '10 at 8:41
source share

To do this for your entire collection, you can also use a loop (based on Niels example):

 db.status.find().forEach(function(doc){ doc._id=doc.UserId; db.status_new.insert(doc); }); db.status_new.renameCollection("status", true); 

In this case, UserId was the new identifier I wanted to use.

+29
Jun 05 '13 at 23:28
source share

In case you want to rename _id in the same collection (for example, if you want to add the _ids prefix):

 db.someCollection.find().snapshot().forEach(function(doc) { if (doc._id.indexOf("2019:") != 0) { print("Processing: " + doc._id); var oldDocId = doc._id; doc._id = "2019:" + doc._id; db.someCollection.insert(doc); db.someCollection.remove({_id: oldDocId}); } }); 

if (doc._id.indexOf ("2019:")! = 0) {... is necessary to prevent an infinite loop, since forEach selects the inserted documents, even using the .snapshot () method.

+4
Mar 10 '18 at 15:45
source share

Here I have a solution to avoid multiple requests to delete loops and old documents.

You can easily create a new idea manually using something like: _id:ObjectId() But knowing that Mongo will automatically assign _id in case of absence, you can use the aggregate to create $project containing all the fields of your document, but skip the _id field . Then you can save it with $out

So if your document:

 { "_id":ObjectId("5b5ed345cfbce6787588e480"), "title": "foo", "description": "bar" } 

Then your request will be:

  db.getCollection('myCollection').aggregate([ {$match: {_id: ObjectId("5b5ed345cfbce6787588e480")} } {$project: { title: '$title', description: '$description' } }, {$out: 'myCollection'} ]) 
0
Jul 31. '18 at 13:23
source share



All Articles