Como definir ids de objetos únicos em documentos incorporados em uma coleção MongoDB

MongoDB's updateMuitos podem ser usados para atualizar todos os documentos que são correspondidos.

Problema

Se, no entanto, você quiser definir novos ObjectIDs exclusivos na sua atualização, você verá que o MongoDB define o mesmo ObjectID para cada entrada:

db.getCollection('mypis_collectedpis').updateMany({}, {$set:
     {apps: {
         "com.picockpit/core": {
             meta: {
                 versão: “2.0”,
                 nome: "PiCockpit Core",
                 imagem: “”,
                 descrição: "PiCockpit.com aplicação central"
                 }
             },
             id: ObjectId()
         },
      ts: ISODate(“2020-07-23T08:42:41.052Z”)}
    })

imagem

Isto porque a ObjectId é criada uma vez e depois usada para cada atualização.

Solução

É necessário iterar sobre os documentos individuais usando um cursor, e definir os ObjectIDs.

Primeiro passo

Atualize / defina os valores que serão os mesmos em todos os seus documentos.

Eu sugiro que os valores distintos sejam definidos como nulos já no início desta etapa:

db.getCollection('mypis_collectedpis').updateMany({}, {$set:
     {apps: {
         "com.picockpit/core": {
             meta: {
                 versão: “2.0”,
                 nome: "PiCockpit Core",
                 imagem: “”,
                 descrição: "PiCockpit.com aplicação central"
                 }
             },
             id: nulo
         },
      ts: ISODate(“2020-07-23T08:42:41.052Z”)}
    })

imagem

NB: Eu uso o Robo 3T para uma experiência mais confortável do que a linha de comando MongoDB.

vais ter:

imagem

Segundo passo

Iterate across the documents, e atualize cada um usando o updateOne:

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

imagem

note a notação de pontos para acessar entradas em um documento incorporado - para a notação de pontos a chave do item tem que estar entre aspas!

A propósito, esta é a saída que isto gera:

imagem

e este é o resultado, para duas entradas distintas:

imagem

imagem

Os ObjectIDs foram atualizados com valores distintos.

Nota importante

Note que neste código não existem bloqueios / transações - para que esta solução funcione, você precisaria ter acesso exclusivo ao banco de dados, ou assegurar que os dados não sejam alterados enquanto você estiver trabalhando no banco de dados.

Caso contrário, algum tipo de esquema de atualização tem que ser colocado em prática - um exercício deixado para o leitor.

Obrigado a Maximilian Schwarzmüller pelo seu curso Udemy MongoDB, e pela excelente documentação online MongoDB!