5

レコードのセットを処理して別のコレクションに保存するrakeタスクがあります。

batch = [] 

Record.where(:type => 'a').each do |r| 
  batch <<  make_score(r)

  if batch.size %100 == 0 
    Score.collection.insert(batch) 
    batch = [] 
  end 
end 

一度に約10万件のレコードを処理しています。残念ながら、20分でQuery response returned CURSOR_NOT_FOUNDエラーが発生します。

mongodbのよくある質問では、タイムアウトを使用またはオフにするように指示されています。タイムアウトを使用すると、すべてが約2〜3倍遅くなります。skiplimit

mongoidと組み合わせてタイムアウトをオフにするにはどうすればよいですか?

4

4 に答える 4

9

MongoDBのドキュメントによると、タイムアウトブール値を渡すことができます。タイムアウトはfalseであり、タイムアウトすることはありません。

collection.find({"type" => "a"}, {:timeout=>false})

あなたの場合:

Record.collection.find({:type=>'a'}, :timeout => false).each ...

また、Mongoで縮小されたマップを調べることをお勧めします。この種のコレクション配列操作に合わせて作成されているようです:http ://www.mongodb.org/display/DOCS/MapReduce

于 2010-10-25T21:53:58.523 に答える
8

mongoid 3では、これを使用できます。

ModelName.all.no_timeout.each do |m|
   "do something with model"
end

これはかなり便利です。

于 2013-11-14T20:30:42.237 に答える
6

少なくとも今のところ、長いルートをたどり、Mongoドライバーを介してクエリを実行する必要があるようです。

Mongoid.database[collection.name].find({ a_query }, { :timeout => false }) do |cursor| 
  cursor.each do |row| 
    do_stuff 
  end 
end
于 2011-01-27T16:30:26.220 に答える
1

これが私が行った回避策です。完全なレコードを保持する配列を作成し、このようにその配列から作業します

products = []

Product.all.each do |p|
products << p
end

products.each do |p|
# Do your magic
end

非常に多数のレコードで作業している場合を除き、すべてのレコードの配列へのダンプは、タイムアウト前に完了する可能性があります。また、大量のレコードや多すぎるレコードを処理する場合にも、メモリを大量に消費することになりますので、注意してください。

于 2011-08-10T09:38:39.617 に答える