我知道我们可以使用
批量更新mongodb中的文档db.collection.update( criteria, objNew, upsert, multi )
在一次数据库调用中,但它是同类的,即所有受影响的文档都遵循一种标准。但我想做的是像
db.collection.update([{criteria1, objNew1}, {criteria2, objNew2}, ...]
,发送多个更新请求,这将更新可能在单个db调用中完全不同的文档或文档类。
我想在我的应用程序中做的是使用复合主键插入/更新一堆对象,如果密钥已经存在,则更新它;否则插入它。
我可以在mongodb的一个组合中完成所有这些吗?
答案 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的存在执行以下两项操作之一:
希望有所帮助
答案 1 :(得分:1)
以您建议的方式进行更新没有任何实际好处。
存在批量插入API并且速度更快的原因是Mongo可以将所有新文档顺序写入内存,并在一次操作中更新索引和其他簿记。
对影响多个文档的更新也会发生类似情况:更新将仅遍历索引一次,并在找到对象时更新对象。
使用多个条件发送多个条件无法从这些优化中获益。每个条件都意味着单独的查询,就像您单独发布每个更新一样。唯一可能的好处是通过连接发送略少的字节。数据库仍然必须单独执行每个查询并单独更新每个文档。
所有会发生的事情是Mongo会在内部对更新进行排队并按顺序执行它们(因为任何时候都只能进行一次更新),这与所有更新都是单独发送完全相同。
单独发送查询的开销不太可能很大,Mongo的全局写锁定无论如何都将成为限制因素。
答案 2 :(得分:1)
我们看到了$ in子句的一些好处。 我们的用例是更新文档中的“状态”以获取大量的记录。 在我们的第一个剪辑中,我们正在进行for循环并逐个进行更新。但后来我们切换到使用$ in子句并且取得了巨大的进步。