2

我正在迭代一个集合(将 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))}

这不会更新字段“年龄”,而一个简单的

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

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

问候,克里斯

4

1 回答 1

1

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

当你迭代时,users.find你会得到一个简单Moped::BSON::Document对象的集合,它们更像 rubyHash​​ 对象而不是其他任何东西。所以当你调用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​​ 驱动程序进行基准测试。如果您可以将代码移植到 javascript,则可以在 mongodb 服务器本身上运行它,这将消除网络延迟,但在执行此类操作时要小心锁定整个数据库。

于 2013-04-17T23:14:20.160 回答