Come aggiornare _id di un documento MongoDB?

Voglio aggiornare _id MongoDB di un documento. So che non è una buona pratica. Ma con qualche motivo tecnico, ho bisogno di aggiornarlo. Ma se provo ad aggiornarlo ho:

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

E l’aggiornamento non è fatto. Come posso davvero aggiornarlo?

Non puoi aggiornarlo. Dovrai salvare il documento usando un nuovo _id , quindi rimuovere il vecchio documento.

 // 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")}) 

Per farlo per tutta la tua collezione puoi anche usare un ciclo (basato sull’esempio di Niels):

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

In questo caso UserId era il nuovo ID che volevo usare

Nel caso in cui, si voglia rinominare _id nella stessa collezione (ad esempio, se si desidera aggiungere un prefisso _id):

 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) {… necessario per impedire il ciclo infinito, poiché forEach seleziona i documenti inseriti, anche attraverso il metodo .snapshot () utilizzato.

Qui ho una soluzione che evita richieste multiple, loop e rimozione di vecchi documenti.

Puoi facilmente creare una nuova idea manualmente usando qualcosa come: _id:ObjectId() Ma sapendo che Mongo assegnerà automaticamente un _id se mancante, puoi usare aggregato per creare un $project contenente tutti i campi del tuo documento, ma omettere il campo _id . Puoi quindi salvarlo con $out

Quindi se il tuo documento è:

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

Quindi la tua richiesta sarà:

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