mongodb find后跟更新语义

时间:2012-01-26 16:13:30

标签: c++ mongodb database nosql

This page显示更新到达先前检索的(查找)文档并查询子元素(数组)以更新它。我几乎需要做同样的事情。示例代码:

> t.find()
{ "_id" : ObjectId("4b97e62bf1d8c7152c9ccb74"), "title" : "ABC",
  "comments" : [ { "by" : "joe", "votes" : 3 }, { "by" : "jane", "votes" : 7 } ] }

> t.update( {'comments.by':'joe'}, {$inc:{'comments.$.votes':1}}, false, true )

有关find-follow-by-update的规则是什么,我在文档中没有注意到这方面的解释。同样的东西是否适用于通过驱动程序使用mongodb?指向相关语义的链接会很有帮助。我正在使用C ++驱动程序。

编辑:自我回答

可以将2个命令合并为一个(这是消除此问题引起的歧义的一种方法),更新的查询部分可以引用数组子元素,$符号将参考它。我假设您只能在更新操作的查询部分中引用一个子元素。在我的情况下,更新操作如下所示:

db.qrs.update ( { "_id" : ObjectId("4f1fa126adf93ab96cb6e848"), "urls.u_id" : 171 }, { "$inc" :  { "urls.$.CC": 1} })

_id正确“填充”正确的唯一行,第二个查询元素"urls.u_id" : 171确保有问题的行具有正确的字段。然后urls.$.CC$inc操作路由到正确的数组条目。

推荐给任何mongodb dev或文档编写者

不要显示具有潜在竞争条件的示例。始终避免显示可以原子方式完成的多个操作。

1 个答案:

答案 0 :(得分:2)

规则相对简单。更新的结果可能会或可能不会对任何后续读取可用,具体取决于许多事物(slaveOk true / false结合使用repsets,使用不同的连接进行更新和查找,写入安全性)。如果您进行安全写入(w> = 1)并在同一连接上执行查找,则可以保证它可用。大多数驱动程序都提供此功能(通常是“requestStart”和“requestDone”)。

所有这一切,为您提供了更好的解决方案,即findAndModify。此操作查找文档,对其进行更新并返回旧版本的文档或新更新的版本。此命令在C ++驱动程序中可用。有关参考,请参阅此处:http://www.mongodb.org/display/DOCS/findAndModify+Command

编辑:请注意,示例中的“查找”仅用于向文档的读者显示集合中文档的结构/模式是将后续“更新”置于上下文中。 “更新”操作决不受前面“查找”的影响。