如何在MongoDB集合中的嵌入式文档中设置唯一的对象ID
MongoDB的updateMany可以用来更新所有被匹配的文档。
问题
然而,如果你想在更新中设置唯一的新ObjectID,你会发现MongoDB为每个条目设置相同的ObjectID。
db.getCollection('mypis_collectedpis').updateMany({}, {$set:
{apps: {
"com.picockpit/core"。{
meta: {
版本。"2.0",
名称:"PiCockpit核心"。
图像。"",
描述。"PiCockpit.com核心应用程序"
}
},
id:ObjectId()
},
ts:ISODate(“2020-07-23T08:42:41.052Z”)}
})
这是因为ObjectId被创建一次,然后用于每次更新。
解决方案
你需要使用游标在各个文件上进行迭代,并设置ObjectIDs。
第一步
更新/设置值,这些值在你的文件中是相同的。
我建议在这一步中首先将不同的值设置为空。
db.getCollection('mypis_collectedpis').updateMany({}, {$set:
{apps: {
"com.picockpit/core"。{
meta: {
版本。"2.0",
名称:"PiCockpit核心"。
图像。"",
描述。"PiCockpit.com核心应用程序"
}
},
id: null
},
ts:ISODate(“2020-07-23T08:42:41.052Z”)}
})
注:我使用Robo 3T,以获得比MongoDB命令行外壳更舒适的体验。
你将得到。
第二步
遍历文件,并使用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()})。
})
请注意,访问嵌入式文件中的条目时使用点符号--对于点符号,项目键必须用引号括起来!
顺便说一下,这是产生的输出。
这就是结果,有两个不同的条目。
ObjectIDs已经用不同的值进行了更新。
重要说明
请注意,在这段代码中,没有锁/没有事务--为了使这个解决方案发挥作用,你需要对数据库有独占的访问权,或者确保在你对数据库进行工作时,数据不会被改变。
否则就必须制定某种更新计划--这是留给读者的练习。
感谢Maximilian Schwarzmüller的Udemy MongoDB课程,以及优秀的MongoDB在线文档。