MongoDB 中的 findAndModify 和 update 有什么区别?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10778493/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 12:40:46  来源:igfitidea点击:

What's the difference between findAndModify and update in MongoDB?

mongodb

提问by chaonextdoor

I'm a little bit confused by the findAndModifymethod in MongoDB. What's the advantage of it over the updatemethod? For me, it seems that it just returns the item first and then updates it. But why do I need to return the item first? I read the MongoDB: the definitive guideand it says that it is handy for manipulating queues and performing other operations that need get-and-set style atomicity. But I didn't understand how it achieves this. Can somebody explain this to me?

我对findAndModifyMongoDB 中的方法有点困惑。它与update方法相比有什么优势?对我来说,它似乎只是先返回项目然后更新它。但是为什么我需要先退货?我阅读了MongoDB:权威指南,它说它对于操作队列和执行其他需要 get-and-set 样式原子性的操作非常方便。但我不明白它是如何实现这一点的。有人可以向我解释一下吗?

采纳答案by Asya Kamsky

If you fetch an item and then update it, there may be an update by another thread between those two steps. If you update an item first and then fetch it, there may be another update in-between and you will get back a different item than what you updated.

如果您获取一个项目然后更新它,那么在这两个步骤之间可能会有另一个线程进行更新。如果您先更新一个项目然后获取它,中间可能会有另一个更新,您将获得与您更新的项目不同的项目。

Doing it "atomically" means you are guaranteed that you are getting back the exact same item you are updating - i.e. no other operation can happen in between.

以“原子”方式执行此操作意味着您可以保证取回与正在更新的项目完全相同的项目 - 即在这两者之间不会发生其他操作。

回答by Yaniv

findAndModifyreturns the document, update does not.

findAndModify返回文档,更新不。

If I understood Dwight Merriman (one of the original authors of mongoDB) correctly, using update to modify a single document i.e.("multi":false} is also atomic. Currently, it should also be faster than doing the equivalent update using findAndModify.

如果我正确理解了 Dwight Merriman(mongoDB 的原作者之一),使用 update 修改单个文档 ie("multi":false} 也是原子的。目前,它也应该比使用findAndModify.

回答by Tamlyn

From the MongoDB docs(emphasis added):

来自MongoDB 文档(添加了重点):

  • By default, both operations modify a single document. However, the update() method with its multi option can modify more than one document.

  • If multiple documents match the update criteria, for findAndModify(), you can specify a sortto provide some measure of control on which document to update. With the default behavior of the update() method, you cannot specify which single document to update when multiple documents match.

  • By default, findAndModify() method returns thepre-modified version of the document. To obtain the updated document, use the new option. The update() method returns a WriteResult object that contains the status of the operation. To return the updated document, use the find() method. However, other updates may have modified the document between your update and the document retrieval. Also, if the update modified only a single document but multiple documents matched, you will need to use additional logic to identify the updated document.

  • Before MongoDB 3.2 you cannot specify a write concern to findAndModify() to override the default write concern whereas you can specify a write concernto the update() method since MongoDB 2.6.

When modifying a single document, both findAndModify() and the update() method atomically update the document.

  • 默认情况下,这两个操作都会修改单个文档。但是,带有 multi 选项的 update() 方法可以修改多个文档

  • 如果多个文档与更新条件匹配,则对于 findAndModify(),您可以指定一种排序以提供对要更新的文档的某种控制措施。使用 update() 方法的默认行为,当多个文档匹配时,您无法指定要更新的单个文档。

  • 默认情况下, findAndModify() 方法返回文档的修改前版本。要获取更新的文档,请使用新选项。update() 方法返回一个包含操作状态的 WriteResult 对象。要返回更新的文档,请使用 find() 方法。但是,其他更新可能在您的更新和文档检索之间修改了文档。此外,如果更新仅修改了单个文档但匹配了多个文档,您将需要使用额外的逻辑来识别更新的文档。

  • 在 MongoDB 3.2 之前,您不能为 findAndModify() 指定写关注来覆盖默认写关注,而自 MongoDB 2.6 起,您可以为 update() 方法指定写关注

修改单个文档时, findAndModify() 和 update() 方法都会自动更新文档。

回答by Roman Kuzmin

One useful class of use cases is counters and similar cases. For example, take a look at this code (one of the MongoDB tests): find_and_modify4.js.

一类有用的用例是计数器和类似用例。例如,看看这个代码(MongoDB 测试之一): find_and_modify4.js

Thus, with findAndModifyyou increment the counter and get its incremented value in one step. Compare: if you (A) perform this operation in two steps and somebody else (B) does the same operation between your steps then A and B may get the same last counter value instead of two different (just one example of possible issues).

因此,随着findAndModify您增加计数器并一步获得其增加的值。比较:如果您 (A) 在两个步骤中执行此操作,而其他人 (B) 在您的步骤之间执行相同的操作,则 A 和 B 可能会获得相同的最后一个计数器值,而不是两个不同的值(只是可能问题的一个示例)。

回答by Manju Kori

We used findAndModify() for Counter operations (inc or dec) and other single fields mutate cases. Migrating our application from Couchbase to MongoDB, I found this API to replace the code which does GetAndlock(), modify the content locally, replace() to save and Get() again to fetch the updated document back. With mongoDB, I just used this single API which returns the updated document.

我们将 findAndModify() 用于计数器操作(inc 或 dec)和其他单字段变异情况。将我们的应用程序从 Couchbase 迁移到 MongoDB,我发现这个 API 替换了执行 GetAndlock() 的代码,在本地修改内容,replace() 以保存和 Get() 再次获取更新的文档。对于 mongoDB,我只使用了这个返回更新文档的 API。