迭代MongoDB中的集合以获取更新

时间:2013-04-17 11:18:03

标签: mongodb loops collections mongoid moped

我正在迭代一个集合(运行Moped作为Ruby驱动程序)但是如何为每个文档更新一个字段?

irb> session = Moped::Session.new(["127.0.0.1:27017"])
irb> session.use :demoapp
irb> users = session[:users]
irb> users.find.each {|u| u.update(age: rand(18..80))}

这不会更新字段“age”,而是简单的

irb> users.find.each {|u| users.find(_id: u["_id"]).update(age: rand(18..80))}

一样。但是迭代一个集合然后在每次迭代中查找id似乎都不是非常有效。那么我怎么能简化呢?我需要一些快速的方法来以这种方式更新数百万个文档。

此致 克里斯

1 个答案:

答案 0 :(得分:1)

你对轻便摩托车的待遇更像是mongoid。轻便摩托车不是ODM - 它是一个低级别的mongodb驱动程序。

当您迭代users.find时,您会收到一组简单的Moped::BSON::Document个对象,这些对象更像是ruby Hash个对象,而不是其他任何对象。所以当你在它们上面调用update时,你只是在内存中更新本地的而不是触及数据库。

类似地

users.find(_id: u["_id"]).update(age: rand(18..80))

没有你想象的那么糟糕。 Moped将其编译为单个update命令 - 它不会获取文档,修改它,然后将其写回。

为了便于开发,你可能会更喜欢使用mongoid,就像这样:

class User
    include Mongoid::Document
    field :age, type: Integer
end 

User.all.each do |u| 
    u.age = rand(18..80)
    u.save!
end

但如果表现至关重要,轻便摩托车会更快。您也可以对官方10gen ruby driver进行基准测试。如果你可以将你的代码移植到javascript,你可以在mongodb服务器上运行它,这可以消除网络延迟,但是在你做这些事情时要小心锁定整个数据库。