[英]Safe+efficient way to modify Mongo objects while iterating over a cursor?
我有一些代码检查Mongo集合中的每个对象(迭代不带参数的find()的结果),并对其中一些进行更改。 看起来这不安全:我的更改被保存,但是当我继续迭代光标时,更改对象的子集(10-15%)会再次出现。 我没有更改文档ID或任何有索引的内容。
我想通过提前抓取所有文档ID(将光标转换为数组)来避免这个问题,但这些是大型集合,所以我真的想避免这种情况。
我注意到默认情况下find()的结果似乎没有任何已定义的顺序,所以我尝试对游标进行显式排序,{“_ id”:1}。 这似乎解决了这个问题 - 无论我修改什么,现在都没有出现过两次。 但我不知道这是不是一个好的/可靠的方法。 据我从文档中可以看出,添加排序并不会使其预先查询所有ID; 如果是这样,那很好,但后来我不知道为什么它会解决这个问题。
改变东西时使用游标是一个坏主意吗?
我正在使用Scala / Casbah,如果这很重要的话。
听起来你想要的是快照查询。 以下是有关如何执行此操作的更多信息:
http://www.mongodb.org/display/DOCS/How+to+do+Snapshotted+Queries+in+the+Mongo+Database
考虑使用修改多个文档的update
命令: http : //docs.mongodb.org/manual/tutorial/modify-documents/
此外,由于您只修改了某些对象,因此请考虑使用仅返回实际要修改的文档而不是扫描整个集合的查询。
迭代find
和修改对象的结果可能看起来更方便和灵活,因为您不仅限于使用更新操作符可以执行的操作,并且您可以使用您选择的语言编写代码来修改文档。 但是,您描述的问题以及其他限制:
http://docs.mongodb.org/manual/faq/developers/#faq-developers-isolate-cursors
例如,快照查询不是100%安全的,并且它们不能与分片集合一起使用,因此如果您以后决定分片,那么您的解决方案将会中断。
如果您需要以更复杂的方式修改大量对象,可以使用map-reduce或聚合管道来解决您的问题:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.