我是Ruby和Mongo的新手,正在处理Twitter数据。我正在使用Ruby 1.9.3和Mongo gems。
我正在查询Mongo中的批量数据,过滤掉一些文档,处理剩余的文档(插入新字段),然后将新文档写入Mongo。
下面的代码工作正常但运行速度相对较慢,因为我循环使用.each,然后一次将新文档插入到Mongo中。
我的问题:如何将其结构化以便批量处理和插入?
cursor = raw.find({'user.screen_name' => users[cur], 'entities.urls' => []},{:fields => params})
cursor.each do |r|
if r['lang'] == "en"
score = r['retweet_count'] + r['favorite_count']
timestamp = Time.now.strftime("%d/%m/%Y %H:%M")
#Commit to Mongo
@document = {:id => r['id'],
:id_str => r['id_str'],
:retweet_count => r['retweet_count'],
:favorite_count => r['favorite_count'],
:score => score,
:created_at => r['created_at'],
:timestamp => timestamp,
:user => [{:id => r['user']['id'],
:id_str => r['user']['id_str'],
:screen_name => r['user']['screen_name'],
}
]
}
@collection.save(@document)
end #end.if
end #end.each
非常感谢任何帮助。
答案 0 :(得分:0)
在你的情况下,没有办法让这更快。您可以做的一件事是以批量检索文件,处理文件并将其重新插入批量文件中,但它仍然很慢。
为了加快速度,你需要做所有处理服务器端,数据已经存在。
如果结果文档不超过16mb,您应该使用aggregate framework of mongodb或者为了更灵活但执行速度更慢(比您的解决方案可能的速度快得多),您可以使用MapReduce framework of mongodb
答案 1 :(得分:0)
你究竟在做什么?为什么不去纯红宝石或纯蒙古(那也是红宝石)?为什么你真的需要加载每一个属性?
我从您的代码中了解到,您实际上是在创建一个全新的文档,我认为这是错误的。
你可以在红宝石方面做到这一点:
cursor = YourModel.find(params)
cursor.each do |r|
if r.lang == "en"
r.score = r.retweet_count + r.favorite_count
r.timestamp = Time.now.strftime("%d/%m/%Y %H:%M")
r.save
end #end.if
end #end.each
当然,您可以在模型中导入include Mongoid::Timestamps
,它会处理您的created_at
和updated_at
属性(它自己创建)
use my_db
获取您的收藏,然后下一个代码将生成您想要的内容
db.models.find({something: your_param}).forEach(function(doc){
doc.score = doc.retweet_count + doc.favorite_count
doc.timestamp = new Timestamp()
db.models.save(doc)
}
);
我不知道你的参数是什么,但是很容易创建它们,而且mongoid也真的做延迟加载,所以如果你不尝试使用属性,它就不会加载它。实际上,您可以节省大量时间而不使用每个属性。 而这些方法,更改现有文档,不会创建另一个。