批量插入Mongo - Ruby

时间:2013-07-17 12:00:48

标签: ruby mongodb optimization twitter

我是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

非常感谢任何帮助。

2 个答案:

答案 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_atupdated_at属性(它自己创建)

在mongoid中,它有点难度 首先使用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也真的做延迟加载,所以如果你不尝试使用属性,它就不会加载它。实际上,您可以节省大量时间而不使用每个属性。 而这些方法,更改现有文档,不会创建另一个。