如何在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在线文档。