将Mongo查询转换为Ruby数组的最佳方法?

时间:2012-06-18 21:01:29

标签: ruby mongodb mongoid

假设我在MongoDB中有一个大型查询(为了本练习的目的,它会返回1M记录),例如:

users = Users.where(:last_name => 'Smith')

如果我循环遍历此结果,请与每个成员一起使用,例如:

users.each do |user|
  # Some manipulation to "user"
  # Some calculation for "user"
  ...
  # Saving "user"
end

我经常会得到一个Mongo游标超时(因为保留的数据库游标超过了默认的超时长度)。我知道我可以延长光标超时,甚至关闭它 - 但这并不总是最有效的方法。所以,我解决这个问题的一种方法是将代码更改为:

users = Users.where(:last_name => 'Smith')
user_array = []
users.each do |u|
    user_array << u
end

然后,我可以遍历user_array(因为它是一个Ruby数组),进行操作和计算,而不必担心MongoDB超时。

这很好,但必须有更好的方法 - 有人有建议吗?

2 个答案:

答案 0 :(得分:2)

如果您的结果集太大而导致游标超时,那么将它完全加载到RAM中并不是一个好主意。

一种常见的方法是批量处理记录。

  1. 获取1000个用户(按_id排序)。
  2. 处理它们。
  3. 获取另一批1000名用户,其中_id大于上次处理用户的_id。
  4. 重复完成。

答案 1 :(得分:0)

对于长时间运行的任务,请考虑使用rails runner。

runner以非交互方式在Rails的上下文中运行Ruby代码。例如:

$ rails runner "Model.long_running_method"

有关详细信息,请参阅:

  

http://guides.rubyonrails.org/command_line.html