使用带有mongoid适配器的Rails3和mongoDB,我如何批量查找mongo DB?我需要获取特定mongo DB集合中的所有记录,并在solr (用于搜索的初始数据索引)中对它们进行索引。
我遇到的问题是,执行Model.all会抓取所有记录并将它们存储到内存中。然后,当我在solr中对它们进行处理和索引时,我的内存就会耗尽,这个过程就会终止。
我正在尝试做的是在mongo中批量查找,这样我就可以一次迭代超过1000条记录,将它们传递给solr进行索引,然后处理下1000条记录,依此类推。
我目前使用的代码是这样做的:
Model.all.each do |r|
Sunspot.index(r)
end对于大约有150万条记录的集合,这会消耗8+ GB的内存并终止进程。在ActiveRecord中,有一个find_in_batches方法,它允许我将查询分成可管理的批处理,从而防止内存失控。然而,对于mongoDB/mongoid,我似乎找不到这样的东西。
我希望能够做这样的事情:
Model.all.in_batches_of(1000) do |batch|
Sunpot.index(batch)
end这将通过每次只做一个可管理的问题集来缓解我的内存问题和查询困难。然而,关于在mongoDB中进行批处理查找的文档很少。我看到很多关于批量插入的文档,但没有批量查找。
发布于 2011-12-23 10:29:19
使用Mongoid,您不需要手动批处理查询。
在Mongoid中,Model.all返回一个Mongoid::Criteria实例。在此条件下调用#each时,Mongo驱动程序游标被实例化并用于迭代记录。这个底层的Mongo驱动程序游标已经批处理了所有记录。默认情况下,batch_size为100。
有关此主题的更多信息,请阅读this comment from the Mongoid author and maintainer。
总而言之,您可以这样做:
Model.all.each do |r|
Sunspot.index(r)
end发布于 2014-05-17 01:26:52
如果您正在迭代一个集合,其中每条记录都需要进行大量处理(即查询每个项的外部API ),那么游标可能会超时。在这种情况下,您需要执行多个查询,以便不使游标保持打开状态。
require 'mongoid'
module Mongoid
class Criteria
def in_batches_of(count = 100)
Enumerator.new do |y|
total = 0
loop do
batch = 0
self.limit(count).skip(total).each do |item|
total += 1
batch += 1
y << item
end
break if batch == 0
end
end
end
end
end下面是一个辅助方法,您可以使用它来添加批处理功能。它的使用方法如下:
Post.all.order_by(:id => 1).in_batches_of(7).each_with_index do |post, index|
# call external slow API
end只要确保你的查询总是有一个order_by就行了。否则,分页可能不会执行您想要的操作。此外,我会坚持使用100个或更少的批次。正如在被接受的答案中所说,Mongoid查询是以100个为一批的,所以在进行处理时,您永远不会想让游标保持打开状态。
发布于 2013-03-05 03:33:32
将批次发送到太阳黑子也更快。我是这样做的:
records = []
Model.batch_size(1000).no_timeout.only(:your_text_field, :_id).all.each do |r|
records << r
if records.size > 1000
Sunspot.index! records
records.clear
end
end
Sunspot.index! recordsno_timeout:防止光标断开连接(默认情况下,在10分钟后)
only:只选择id和字段,它们实际上是索引的
batch_size:获取1000个条目,而不是100个
https://stackoverflow.com/questions/7041224
复制相似问题