Cómo establecer ids de objetos únicos en documentos incrustados en una colección de MongoDB
El updateMany de MongoDB se puede utilizar para actualizar todos los documentos que coincidan.
Problema
Sin embargo, si quiere establecer nuevos ObjectIDs únicos en su actualización, encontrará que MongoDB establece el mismo ObjectID para cada entrada:
db.getCollection('mypis_collectedpis').updateMany({}, {$set:
{apps: {
"com.picockpit/core": {
meta: {
versión: "2.0",
nombre: "PiCockpit Core",
imagen: "",
descripción: "Aplicación principal de PiCockpit.com"
}
},
id: ObjectId()
},
ts: ISODate(“2020-07-23T08:42:41.052Z”)}
})
Esto se debe a que el ObjectId se crea una vez y luego se utiliza para cada actualización.
Solución
Es necesario iterar sobre los documentos individuales utilizando un cursor, y establecer los ObjectIDs.
Primer paso
Actualice / establezca los valores que serán los mismos en todos sus documentos.
Sugiero establecer los valores distintos a null al principio en este paso ya:
db.getCollection('mypis_collectedpis').updateMany({}, {$set:
{apps: {
"com.picockpit/core": {
meta: {
versión: "2.0",
nombre: "PiCockpit Core",
imagen: "",
descripción: "Aplicación principal de PiCockpit.com"
}
},
id: null
},
ts: ISODate(“2020-07-23T08:42:41.052Z”)}
})
NB: Utilizo el Robo 3T para una experiencia más cómoda que el shell de la línea de comandos de MongoDB.
...obtendrás:
Segundo paso
Iterar a través de los documentos, y actualizar cada uno usando updateOne:
db.getCollection('mypis_collectedpis').find().forEach((pi) => {
print("Actualizando" + pi.name + " con ObjectId: " + pi._id);
db.getCollection('mypis_collectedpis').updateOne({_id: pi._id}, {$set: {"apps.id": ObjectId()}});
})
tenga en cuenta la notación de puntos para acceder a las entradas de un documento incrustado - ¡para la notación de puntos la clave del elemento debe ir entre comillas!
Por cierto, esta es la salida que genera:
y este es el resultado, para dos entradas distintas:
Los ObjectIDs han sido actualizados con valores distintos.
Nota importante
Tenga en cuenta que en este código no hay bloqueos / no hay transacciones - para que esta solución funcione, tendría que tener acceso exclusivo a la base de datos, o asegurarse de que los datos no se modifican mientras está trabajando en la base de datos.
De lo contrario, habrá que establecer algún tipo de esquema de actualización, un ejercicio que se deja al lector.
Gracias a Maximilian Schwarzmüller por su curso de MongoDB en Udemy y por la excelente documentación en línea de MongoDB.