Come impostare gli id unici degli oggetti nei documenti incorporati in una collezione MongoDB

L'updateMany di MongoDB può essere usato per aggiornare tutti i documenti che corrispondono.

Problema

Se, tuttavia, vuoi impostare nuovi ObjectID unici nel tuo aggiornamento, scopriresti che MongoDB imposta lo stesso ObjectID per ogni voce:

db.getCollection('mypis_collectedpis').updateMany({}, {$set:
     {apps: {
         "com.picockpit/core": {
             meta: {
                 versione: "2.0",
                 nome: "PiCockpit Core",
                 immagine: "",
                 descrizione: "Applicazione principale di PiCockpit.com"
                 }
             },
             id: ObjectId()
         },
      ts: ISODate(“2020-07-23T08:42:41.052Z”)}
    })

immagine

Questo perché l'ObjectId viene creato una volta e poi usato per ogni aggiornamento.

Soluzione

È necessario iterare sui singoli documenti usando un cursore, e impostare gli ObjectID.

Primo passo

Aggiornare/impostare i valori che saranno gli stessi in tutti i documenti.

Suggerisco di impostare i valori distinti su null all'inizio già in questo passo:

db.getCollection('mypis_collectedpis').updateMany({}, {$set:
     {apps: {
         "com.picockpit/core": {
             meta: {
                 versione: "2.0",
                 nome: "PiCockpit Core",
                 immagine: "",
                 descrizione: "Applicazione principale di PiCockpit.com"
                 }
             },
             id: null
         },
      ts: ISODate(“2020-07-23T08:42:41.052Z”)}
    })

immagine

NB: Io uso Robo 3T per un'esperienza più comoda della shell della linea di comando di MongoDB.

otterrete:

immagine

Secondo passo

Iterare attraverso i documenti, e aggiornare ciascuno usando updateOne:

db.getCollection('mypis_collectedpis').find().forEach((pi) => {
     print("Aggiornamento" + pi.name + " con ObjectId: " + pi._id);
     db.getCollection('mypis_collectedpis').updateOne({_id: pi._id}, {$set: {"apps.id": ObjectId()}});
     })

immagine

notate la notazione a punti per accedere alle voci in un documento incorporato - per la notazione a punti la chiave dell'elemento deve essere racchiusa tra virgolette!

A proposito, questo è l'output che genera:

immagine

e questo è il risultato, per due voci distinte:

immagine

immagine

Gli ObjectID sono stati aggiornati con valori distinti.

Nota importante

Notate che in questo codice non ci sono blocchi / transazioni - perché questa soluzione funzioni, dovreste avere accesso esclusivo al database, o assicurarvi che i dati non vengano modificati mentre state lavorando sul database.

Altrimenti bisogna mettere in atto un qualche schema di aggiornamento - un esercizio lasciato al lettore.

Grazie a Maximilian Schwarzmüller per il suo corso Udemy MongoDB, e l'eccellente documentazione online di MongoDB!