How to set unique object ids in embedded documents across a MongoDB collection
MongoDB’s updateMany can be used to update all documents which are matched.
Problem
If, however, you want to set unique new ObjectIDs in your update, you would find that MongoDB sets the same ObjectID for every entry:
db.getCollection(‘mypis_collectedpis’).updateMany({}, {$set:
{apps: {
“com.picockpit/core”: {
meta: {
version: “2.0”,
name: “PiCockpit Core”,
image: “”,
description: “PiCockpit.com core application”
}
},
id: ObjectId()
},
ts: ISODate(“2020-07-23T08:42:41.052Z”)}
})
This is because the ObjectId is created once and then used for every update.
Solution
You need to iterate over the individual documents using a cursor, and to set the ObjectIDs.
First step
Update / set the values which will be the same across your documents.
I suggest setting the distinct values to null at first in this step already:
db.getCollection(‘mypis_collectedpis’).updateMany({}, {$set:
{apps: {
“com.picockpit/core”: {
meta: {
version: “2.0”,
name: “PiCockpit Core”,
image: “”,
description: “PiCockpit.com core application”
}
},
id: null
},
ts: ISODate(“2020-07-23T08:42:41.052Z”)}
})
NB: I use Robo 3T for a more comfortable experience than the MongoDB command line shell.
you will get:
Second step
Iterate across the documents, and update each using updateOne:
db.getCollection(‘mypis_collectedpis’).find().forEach((pi) => {
print(“Updating” + pi.name + ” with ObjectId: ” + pi._id);
db.getCollection(‘mypis_collectedpis’).updateOne({_id: pi._id}, {$set: {“apps.id”: ObjectId()}});
})
note the dot notation for accessing entries in an embedded document – for the dot notation the item key has to be enclosed in quotation marks!
By the way this is the output this generates:
and this is the result, for two distinct entries:
The ObjectIDs have been updated with distinct values.
Important note
Note that in this code there are no locks / no transactions – for this solution to work, you would need to have exclusive access to the database, or ensure that the data is not changed while you’re working on the database.
Otherwise some kind of update scheme has to be put in place – an exercise left to the reader.
Thanks go to Maximilian Schwarzmüller for his Udemy MongoDB course, and the excellent MongoDB online documentation!