【问题标题】:Upsert an array of items with MongoDB使用 MongoDB 插入一组项目
【发布时间】:2015-07-20 05:25:27
【问题描述】:

我有一个要插入到 MongoDB 集合中的对象数组,但是我想先检查每个项目是否已经存在于集合中。如果不存在则插入,如果存在则不插入。

经过一些谷歌搜索后,看起来我最好使用将 upsert 属性设置为 true 的更新方法。

如果我将单个项目传递给它,并且如果我遍历我的数组并一次插入一个项目,这似乎工作正常,但是我不确定这是否是正确的方法,或者如果它是最有效的。这是我目前正在做的事情:

var data = [{}, {}, ... {}];

for (var i = 0; i < data.length; i++) {

  var item = data[i];

  collection.update(
    {userId: item.id},
    {$setOnInsert: item},
    {upsert: true},
    function(err, result) {

      if (err) {
        // Handle errors here
      }

  });

}

遍历我的数组并一个接一个地插入它们是最有效的方法,还是有更好的方法?

【问题讨论】:

    标签: arrays node.js mongodb


    【解决方案1】:

    我可以在这里看到两个选项,具体取决于您的确切需求:

    • 如果您需要插入或更新,请使用upsert query。在这种情况下,如果对象已经存在,您将对其进行更新——假设您的文档将包含一些内容,这意味着您可能会覆盖某些字段的先前值。如您所见,使用 $setOnInsert 可以缓解该问题。
    • 如果您需要插入或忽略,请在相关字段上添加unique index,并让插入在重复键上失败。由于您有多个要插入的文档,您可以使用unordered insert 将它们全部发送到一个数组中(即:将ordered 选项设置为false),这样MongoDB 将继续插入剩余的文档以防出现错误其中。

    关于性能,第二个选项 MongoDB 将使用索引来查找可能的重复项。所以很有可能这会表现得更好。

    【讨论】:

    • 完美,这正是我所需要的。我确实开始尝试插入整个数组,当它遇到重复时失败并停止,这就是为什么我认为我可能需要按照我在问题中概述的方式进行操作。我不知道即使某些插入失败,您也可以使用无序插入来继续插入。谢谢!
    • @Sylvain Leroux 从 Mongo 3.3 开始,这仍然是实现这一目标的最佳方式吗?看起来效率低下。谢谢。
    • @Stanislasdrg 我快速浏览了 3.4 发行说明 (docs.mongodb.com/manual/release-notes/3.4) 并没有看到任何可能使该说明无效的内容,或者我错过了它?至于这是“低效”:你能详细说明一下吗? FWIW,使用索引将允许在触摸数据之前及早检测冲突。这也将确保插入是原子的,与 read-check-then-write 解决方案相反,因此如果两个并发访问同时尝试修改同一个文档,您将不会有并发读取操作看到脏数据或竞争条件.
    • @SylvainLeroux 我是 Mongo 的新手,因此想看看这是否是最好的方法。来自 SQL 我曾经批量插入。感谢您的周到答复。 S
    猜你喜欢
    • 2012-05-10
    • 2020-04-05
    • 1970-01-01
    • 1970-01-01
    • 2018-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-09
    相关资源
    最近更新 更多