【问题标题】:MongoDB + Ruby: updating records in an iterationMongoDB + Ruby:在迭代中更新记录
【发布时间】:2012-02-03 21:37:55
【问题描述】:

使用 MongoDB 和 Ruby 驱动程序,我正在尝试计算我的应用中玩家的排名,因此我按(在本例中)俯卧撑进行排序,然后为每个对象添加排名字段和值。

pushups = coll.find.sort(["pushups", -1] )
pushups.each_with_index do |r, idx| 
    r[:pushups_rank] = idx + 1
    coll.update( {:id => r }, r, :upsert => true)
    coll.save(r)
end

这种方法确实有效,但这是迭代对象并更新每个对象的最佳方法吗?有没有更好的方法来计算玩家的排名?

【问题讨论】:

    标签: ruby mongodb


    【解决方案1】:

    另一种方法是通过执行 javascript 函数在服务器上进行整个更新:

    update_rank = "function(){
     var rank=0;
     db.players.find().sort({pushups:-1}).forEach(function(p){
       rank +=1;
       p.rank = rank;
       db.players.save(p);
     });
    }"
    cn.eval( update_rank )
    

    (代码假设您在 mongo 中有一个“玩家”集合,还有一个 ruby​​ 变量 cn 保存到您的数据库的连接)

    【讨论】:

    • 我认为这也是正确的方法。请注意,使用 $set 更新而不是保存可能更有效:db.players.update({_id: p._id}, {$set: {rank: rank}}) 或其他东西
    • 还要注意 eval 会锁定整个数据库。这不会随着大量并发请求和/或随着玩家的增长而扩展。 FWIW,我也在 MongoDB 中进行排名,并将特定逻辑切换到 Redis 排序集。我在博客中讲述了我的积极经历:openmymind.net/2011/5/8/…
    • 哦,我确实在我的研究中看到了你的帖子,@KarlSeguin。那里的东西很棒!
    猜你喜欢
    • 2014-11-16
    • 2017-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多