Como posso consultar o MongoDB usando mongóides/trilhos sem tempo?
-
26-09-2019 - |
Pergunta
Eu tenho uma tarefa de rake que processa um conjunto de registros e o salva em outra coleção:
batch = []
Record.where(:type => 'a').each do |r|
batch << make_score(r)
if batch.size %100 == 0
Score.collection.insert(batch)
batch = []
end
end
Estou processando cerca de 100 mil registros por vez. Infelizmente aos 20 minutos, eu recebo um Query response returned CURSOR_NOT_FOUND
erro.
O MONGODB Perguntas frequentes diz para usar skip
e limit
Ou desative os tempos limite, usando tudo o que tudo foi sobre ~ 2-3 vezes mais lento.
Como posso desligar os tempos limite em conjunto com o mongóide?
Solução
o Docs MongoDB diga que você pode passar em um tempo limite booleano e o tempo limite é falso, nunca vai tempo limite
collection.find({"type" => "a"}, {:timeout=>false})
No seu caso:
Record.collection.find({:type=>'a'}, :timeout => false).each ...
Eu também recomendo que você procure o mapa reduzido com o Mongo. Parece que o Tailer feito para esse tipo de manipulação de matriz de coleções: http://www.mongodb.org/display/docs/mapreduce
Outras dicas
Em Mongoid 3, você pode usar isso:
ModelName.all.no_timeout.each do |m|
"do something with model"
end
O que é bastante útil.
Parece que, por enquanto, pelo menos, você precisa seguir o caminho longo e a consulta através do motorista Mongo:
Mongoid.database[collection.name].find({ a_query }, { :timeout => false }) do |cursor|
cursor.each do |row|
do_stuff
end
end
Aqui está a solução alternativa que eu fiz. Crie uma matriz para manter os registros completos e trabalhar dessa matriz como esta
products = []
Product.all.each do |p|
products << p
end
products.each do |p|
# Do your magic
end
O despejo de todos os registros na matriz provavelmente terminará antes do tempo limite, a menos que você esteja trabalhando em um número extremamente grande de registros. Além disso, isso vai consumir muita memória, caso você esteja lidando com registros grandes ou demais, então mantenha essa mente.