Как я могу запросить MongoDB, используя Mongoid / Rails без времени?
-
26-09-2019 - |
Вопрос
У меня есть задача грабли, которая обрабатывает набор записей и сохраняет его в другой коллекции:
batch = []
Record.where(:type => 'a').each do |r|
batch << make_score(r)
if batch.size %100 == 0
Score.collection.insert(batch)
batch = []
end
end
Я обработаю около 100К записей за раз. К сожалению, через 20 минут, я получаю Query response returned CURSOR_NOT_FOUND
ошибка.
Монгодб Вопросы-Ответы говорит использовать skip
а также limit
Или выключите тайм-ауты, используя их все, что было около ~ 2-3 раза медленнее.
Как я могу выключить тайм-ауты в сочетании с монгоидом?
Решение
То Документы MongoDB Скажем, вы можете пройти в булеве на тайм-ауте, и это время таймана ложно, это никогда не будет таймаутом
collection.find({"type" => "a"}, {:timeout=>false})
В твоем случае:
Record.collection.find({:type=>'a'}, :timeout => false).each ...
Я также рекомендую вам посмотреть на карту - уменьшен с Mongo. Кажется, что приспособлен для такого рода манипуляции массива коллекции: http://www.mongodb.org/display/docs/maprecuce
Другие советы
В Монгоиде 3 вы можете использовать это:
ModelName.all.no_timeout.each do |m|
"do something with model"
end
Который довольно удобно.
Кажется, пока, по крайней мере, вам нужно идти длинный маршрут и запрос через драйвер Mongo:
Mongoid.database[collection.name].find({ a_query }, { :timeout => false }) do |cursor|
cursor.each do |row|
do_stuff
end
end
Вот обходной путь я сделал. Создайте массив, чтобы держать полные записи и работать с этого массива, как это
products = []
Product.all.each do |p|
products << p
end
products.each do |p|
# Do your magic
end
Образование всех записей в массив, скорее всего, закончится в течение периода времени ожидания, если вы не работаете над чрезвычайно большим количеством записей. Кроме того, это собирается потреблять слишком много памяти на случай, если вы имеете дело с большими или слишком многими записями, так что сохраните этот разум.