【问题标题】:MongoDB insertMany and skip duplicatesMongoDB insertMany并跳过重复项
【发布时间】:2020-08-12 06:44:32
【问题描述】:

我正在尝试将 insertMany() 项目添加到我的 Mongo 数据库中,但我想跳过重复的 ID。
我正在使用Node.jsmongodb

我有一些数据:

const myExampleData = [
   {_id:'someId1', name:'I am example'},
   {_id:'someId2', name:'I am second example'}
];

我想像这样插入它们:

dbo.collection(collectionName).insertMany(myExampleData).catch(err=>{
    console.error(err);
});

假设someId1 已经存在。我不想覆盖它。我只是想跳过它。在当前情况下,它不会插入someId2。一旦抛出重复异常,它就会停止。

有没有办法插入多个并跳过重复项?


可能的问题重复。

我发现线程 MongoDB insert without duplicates 建议使用 update()upsert 而不是 insert(),这对于一项可能很好。但是有多少项目呢?据我所知updateMany() 会用相同的值更新所有过滤的行,但我想插入不同的值。

【问题讨论】:

    标签: node.js mongodb mongodb-query


    【解决方案1】:

    检查您的声明:

    假设 someId1 已经存在。我不想覆盖它。 我只是想跳过它。

    所以您只是想跳过重复的文档,因为您的意图不是用最新数据更新重复的文档 - 所以不需要使用 .update(),您仍然可以使用 .insertMany() 通过传入标志 @987654323 来执行此操作@ 在查询选项中:

    有序:可选。一个布尔值,指定 mongod 实例是否应该执行有序或无序插入。默认为 true

    db.collection.insertMany(
       [ <document 1> , <document 2>, ... ],
       {
         ordered: <boolean>
       }
    )
    

    您的代码:

    dbo.collection(collectionName).insertMany(myExampleData, {ordered : false }).catch(err=>{
        console.error(err);
    })
    

    就好像你正在检查 _id 它将具有默认唯一索引 & 任何传入的重复实际上都会引发错误,使用 ordered : false 我们正在使这个插入操作无序,因为我们正在跳过所有传入的重复项并继续进行而不实际抛出任何错误。

    【讨论】:

    • 它工作正常。谢谢你。你写了在没有实际抛出任何错误的情况下继续进行。但实际上它仍然会引发错误。在err.writeErrors 中记录了所有重复项。正如文档中所写,只是为了澄清:排除写入关注错误,有序操作在错误后停止,而无序操作继续处理队列中任何剩余的写入操作
    • @Jax-p :我的意图是当我说 - 实际上没有抛出任何错误 - 意味着在不阻塞实际插入操作的情况下将继续插入其余文档, 是的,您可以找到那些未插入的 id 将被记录以供将来参考.. :-)
    【解决方案2】:

    您可以使用 bulkWrite 执行操作并获得类似的结果。例如,在 mongo shell 中:

       db.collectionName.bulkWrite(
          [
             { updateOne :
                {
                   "filter" : { _id:'someId1'},
                   "update" : { $set : { name:'I am example'}},
                   "upsert" : true
                }
             },
            { updateOne :
                {
                   "filter" : { _id:'someId2' },
                   "update" : { $set : { name:'I am second example'} },
                  "upsert" : true
                }
             },
          ]
       );
    

    运行上述代码只会在第一次运行时插入两个文档。并且不会在后续运行中给您任何错误。

    【讨论】:

      猜你喜欢
      • 2016-08-28
      • 1970-01-01
      • 2015-01-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多