【问题标题】:Bulk Insert into Mongo - Ruby批量插入 Mongo - Ruby
【发布时间】:2013-07-15 23:22:32
【问题描述】:

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

非常感谢任何帮助。

【问题讨论】:

  • 您是否尝试将所有文​​档写入文件,然后通过调用系统命令mongoimport -d <db> -c <collection> < file 插入它们?
  • 只是正常的事情:关闭索引,关闭 write_concerns/安全模式......,把它放在更快的磁盘上......

标签: ruby mongodb optimization twitter


【解决方案1】:

在你的情况下,没有办法让这个速度更快。您可以做的一件事是批量检索文档、处理它们并批量重新插入它们,但这仍然会很慢。

为了加快速度,您需要在数据已经存在的服务器端进行所有处理。

如果结果文档不超过 16mb,您应该使用aggregate framework of mongodb,或者为了获得更大的灵活性但执行速度较慢(比您的解决方案的潜力快得多),您可以使用MapReduce framework of mongodb

【讨论】:

    【解决方案2】:

    你到底在做什么?为什么不去纯红宝石或纯蒙戈(那也是红宝石)?为什么你真的需要加载每一个属性?

    我从您的代码中了解到,您实际上创建了一个全新的文档,我认为这是错误的。

    你可以在 ruby​​ 方面做到这一点:

    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 确实会延迟加载,所以如果你不尝试使用属性,它不会加载它。您实际上可以节省大量时间,而不是使用每个属性。 而这些方法,改变现有的文件,并不会创建另一个。

    【讨论】:

      猜你喜欢
      • 2013-07-04
      • 1970-01-01
      • 2014-08-21
      • 1970-01-01
      • 1970-01-01
      • 2011-02-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多