0

MongoDB に次のような大規模なクエリがあるとします (この演習では、1M レコードを返すとします)。

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

この結果をループすると、各メンバーを次のように操作します。

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

多くの場合、Mongo カーソルのタイムアウトが発生します (予約されているデータベース カーソルがデフォルトのタイムアウトの長さを超えているため)。カーソルのタイムアウトを延長したり、オフにしたりできることはわかっていますが、これが常に最も効率的な方法とは限りません。したがって、これを回避する 1 つの方法は、コードを次のように変更することです。

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

次に、MongoDB のタイムアウトを気にせずに、(Ruby 配列であるため) user_array をループして操作と計算を行うことができます。

これは問題なく動作しますが、もっと良い方法が必要です。誰か提案がありますか?

4

2 に答える 2

3

結果セットが大きすぎてカーソル タイムアウトが発生する場合は、結果セット全体を RAM にロードすることはお勧めできません。

一般的なアプローチは、バッチでレコードを処理することです。

  1. 1000 人のユーザーを取得します (_id でソート)。
  2. それらを処理します。
  3. _id が最後に処理されたユーザーの _id より大きい 1000 ユーザーの別のバッチを取得します。
  4. 完了するまで繰り返します。
于 2012-06-18T21:08:46.313 に答える
0

長時間実行されるタスクについては、Rails Runner の使用を検討してください。

runner は、Rails のコンテキストで非対話的に Ruby コードを実行します。例えば:

$ rails runner "Model.long_running_method"

詳細については、以下を参照してください。

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

于 2012-06-18T21:11:07.777 に答える