2012-02-02 91 views
2

使用MongoDB和Ruby驅動程序,我試圖計算我的應用中玩家的排名,所以我按照(在這種情況下)俯臥撐進行排序,然後添加一個排名字段和每個對象的值。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 

這種方法確實有效,但這是迭代對象並更新每個對象的最佳方法嗎?有沒有更好的方法來計算玩家的等級?

回答

3

另一種方法是通過執行一個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) 

(代碼假設你在蒙戈有一個「播放器」收集和可變cn紅寶石是持有連接到您的數據庫)

+0

我喜歡這種方法! – yalestar 2012-02-03 22:05:50

+0

我認爲這也是正確的做法。請注意,使用帶有$ set而不是保存的更新可能會更有效:db.players.update({_ id:p._id},{$ set:{rank:rank}})或其他東西 – 2012-02-04 00:26:58

+1

另請注意,eval鎖整個數據庫。這不會隨着大量的併發請求和/或隨着玩家的增長而擴展。 FWIW,我也在MongoDB中進行排名,並且將特定邏輯切換到Redis排序集。我寫了一篇關於我的積極體驗的文章:http://openmymind.net/2011/5/8/Practical-NoSQL-Solving-a-Real-Problem-w-Mongo-Red/ – 2012-02-04 00:29:57