I want update an _id MongoDB of one document. I know it\'s not a really good pratice. But with some technical reason, I need update it. But If I try to update it I have :
> db.clients.update({\'_id\':ObjectId(\"4cc45467c55f4d2d2a000002\")}, {\'$set\':{\'_id\':ObjectId(\"4c8a331bda76c559ef000004\")}});
Mod on _id not allowed
And the update is not made. How I can really update it ?
You cannot update it. You\'ll have to save the document using a new _id
, and then remove 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\")})
To do it for your whole 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 ID I wanted to use
In case, you want to rename _id in same collection (for instance, if you want to prefix some _ids):
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) {... needed to prevent infinite loop, since forEach picks the inserted docs, even throught .snapshot() method used.
Here I have a solution that avoid multiple requests, for loops and old document removal.
You can easily create a new idea manually using something like:_id:ObjectId()
But knowing Mongo will automatically assign an _id if missing, you can use aggregate to create a $project
containing all the fields of your document, but omit the field _id. You can then save it with $out
So if your document is:
{
\"_id\":ObjectId(\"5b5ed345cfbce6787588e480\"),
\"title\": \"foo\",
\"description\": \"bar\"
}
Then your query will be:
db.getCollection(\'myCollection\').aggregate([
{$match:
{_id: ObjectId(\"5b5ed345cfbce6787588e480\")}
}
{$project:
{
title: \'$title\',
description: \'$description\'
}
},
{$out: \'myCollection\'}
])