2012-06-18 92 views
0

比方说,我在MongoDB中一个大的查询(此练习的目的说出来返回1M记录),如:将Mongo查询转换为Ruby数组的最佳方法?

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

如果我通过这个结果循环,每个成员的工作,喜欢的东西:

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

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

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

,我可以通过user_array循环(因为它是一个Ruby数组),做操作和计算,而不必担心一个MongoDB的超时。

这工作正常,但必须有更好的方法 - 有没有人有建议?

+4

没有'to_a'? – tokland

+0

如果有的话,我会觉得很愚蠢。现在测试@tokland – jbnunn

+0

是的,Users.where(:last_name =>'Smith').to_a的作品。谢谢+1 ...在下面的Sergio的评论中,我将实现他的批处理方法,再加上Ruby的本地to_a,而不是手动循环。谢谢 – jbnunn

回答

2

如果您的结果集太大,导致光标超时,则将其全部加载到RAM并不是一个好主意。

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

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

好的方法。和“大于_id”支持_id的标准BSON格式? – jbnunn

+0

是的,客观排序很好。 –

0

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

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

$ rails runner "Model.long_running_method" 

有关详细信息,请参阅:

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

+0

有趣。我不知道关于rails runner,我确定我可以在某处找到它的用处,但不确定它会解决任何MongoDB特定的超时。 – jbnunn

相关问题