Comment mettre à jour le _id d’un document MongoDB?

Je veux mettre à jour un _id MongoDB d’un document. Je sais que ce n’est pas vraiment une bonne pratique. Mais avec une raison technique, j’ai besoin de le mettre à jour. Mais si j’essaie de le mettre à jour, j’ai:

> db.clients.update({'_id':ObjectId("4cc45467c55f4d2d2a000002")}, {'$set':{'_id':ObjectId("4c8a331bda76c559ef000004")}}); Mod on _id not allowed 

Et la mise à jour n’est pas faite. Comment puis-je vraiment le mettre à jour?

Vous ne pouvez pas le mettre à jour. Vous devrez enregistrer le document en utilisant un nouveau _id , puis supprimer l’ancien 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")}) 

Pour le faire pour toute votre collection, vous pouvez également utiliser une boucle (basée sur l’exemple de Niels):

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

Dans ce cas, UserId était le nouvel identifiant que je voulais utiliser

Dans le cas où vous souhaitez renommer _id dans la même collection (par exemple, si vous voulez préfixer des _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) {… nécessaire pour empêcher une boucle infinie, car forEach sélectionne la documentation insérée, même en utilisant la méthode .snapshot () utilisée.

J’ai ici une solution qui évite les demandes multiples, les boucles et la suppression des anciens documents.

Vous pouvez facilement créer une nouvelle idée manuellement en utilisant quelque chose comme: _id:ObjectId() Mais sachant que Mongo affectera automatiquement un _id s’il est manquant, vous pouvez utiliser l’agrégat pour créer un $project contenant tous les champs de votre document, mais omettre le champ _id . Vous pouvez ensuite l’enregistrer avec $out

Donc, si votre document est:

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

Votre requête sera alors:

  db.getCollection('myCollection').aggregate([ {$match: {_id: ObjectId("5b5ed345cfbce6787588e480")} } {$project: { title: '$title', description: '$description' } }, {$out: 'myCollection'} ])