2012-06-18 89 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

相關問題