mongodb中的异构批量更新

时间:2011-10-19 10:55:45

标签: mongodb

我知道我们可以使用

批量更新mongodb中的文档
db.collection.update( criteria, objNew, upsert, multi )

在一次数据库调用中,但它是同类的,即所有受影响的文档都遵循一种标准。但我想做的是像

db.collection.update([{criteria1, objNew1}, {criteria2, objNew2}, ...]

,发送多个更新请求,这将更新可能在单个db调用中完全不同的文档或文档类。

我想在我的应用程序中做的是使用复合主键插入/更新一堆对象,如果密钥已经存在,则更新它;否则插入它。

我可以在mongodb的一个组合中完成所有这些吗?

3 个答案:

答案 0 :(得分:6)

这是两个单独的问题。到第一个;没有MongoDB本机机制来批量发送条件/更新对,尽管技术上自己在循环中这样做必然与任何本机批量支持一样高效。

检查是否存在基于嵌入文档的文档(您称之为复合键,但为了避免混淆,为了避免混淆,最好在这种情况下使用mongo名称)并插入/更新取决于在那个存在检查可以用upsert完成:

文件A:

{
    _id: ObjectId(...),
    key: {
        name: "Will",
        age: 20
    }
}

db.users.update({name:"Will", age:20}, {$set:{age: 21}}), true, false)

此upsert(如果没有文档符合条件,则使用insert进行更新)将根据文档A的存在执行以下两项操作之一:

  • 存在:在现有文档上执行更新“$ set:{age:21}”
  • 不存在:使用字段“name”和字段创建新文档 “年龄”分别为“Will”和“20”(基本上是 将条件复制到新文档中,然后应用更新 ($集:{年龄:21})。最终结果是带有“name”=“Will”和的文档 “年龄”= 21。

希望有所帮助

答案 1 :(得分:1)

以您建议的方式进行更新没有任何实际好处。

存在批量插入API并且速度更快的原因是Mongo可以将所有新文档顺序写入内存,并在一次操作中更新索引和其他簿记。

对影响多个文档的更新也会发生类似情况:更新将仅遍历索引一次,并在找到对象时更新对象。

使用多个条件发送多个条件无法从这些优化中获益。每个条件都意味着单独的查询,就像您单独发布每个更新一样。唯一可能的好处是通过连接发送略少的字节。数据库仍然必须单独执行每个查询并单独更新每个文档。

所有会发生的事情是Mongo会在内部对更新进行排队并按顺序执行它们(因为任何时候都只能进行一次更新),这与所有更新都是单独发送完全相同。

单独发送查询的开销不太可能很大,Mongo的全局写锁定无论如何都将成为限制因素。

答案 2 :(得分:1)

我们看到了$ in子句的一些好处。 我们的用例是更新文档中的“状态”以获取大量的记录。 在我们的第一个剪辑中,我们正在进行for循环并逐个进行更新。但后来我们切换到使用$ in子句并且取得了巨大的进步。