2013-08-26 58 views
1

我有mongodb集合users。 每個用戶都有一個名爲rating的字段,該字段介於1和5之間。這意味着當用戶對另一個用戶投票時,他'給''他的投票,這是一個介於1和5之間的數字。我在將該數據存儲在mongo文檔中時遇到問題東陽我有rating現場查詢用戶收集和我有atomicly更新...在MongoDB文檔中更新和查詢評級

  1. 如果我同時存儲評級和票數時,我可以更新votes_number$inc運營商,但我不能atomicly設置rating = ((rating*votes) + vote_val)/(votes+1)

  2. 我可以只保留票數和票數總和ð更新使用$inc但我不能像WHERE votes_sum/votes_num > 3查詢都...

有沒有辦法解決這個問題?

回答

2

你可以做的是使用上面的選項2,然後將其與緩存的結果字段組合。您可以設置數據流,以便通過在更新中使用過濾器謂詞,使結果字段與文檔的其餘部分保持一致。

第一步是添加一個新的字段到您的模式,這將是您的緩存評級字段。這將允許您執行範圍查詢,而無需執行動態分割。您遇到的問題是您無法自動增加votes_sum & votes_num字段並在相同的原子操作中設置緩存的評分字段。所以這就是你所做的。

1)以原子遞增votes_sum和votes_num字段
2)抓鬥的_id,votes_sum & votes_num爲更新後的文檔
3)更新評級,但,作爲過濾器謂語的一部分,包括_id,預期votes_sum和期望的票數字段。

db.collection.update({_id: $id, votes_sum: $votes_sum, votes_num: $votes_num}, {$set: {rating: $votes_sum/$votes_num}}); 

這將確保自更新文檔以來沒有任何更改。如果其他人出現並在更新這些字段並更新這些字段之間更新它們並生成評級,則該文檔將不會在更新語句的查找部分中返回,因此將不會使用陳舊數據更新

此模式需要寫入在MongoDB中處於文檔級別是原子的優勢,因此您不必擔心文檔內數據的一致性。好的是,評級將被正確設置,因爲每次更新votes_sum和votes_num字段的操作後都會更新評級。

看到這裏的一些示例代碼:http://docs.mongodb.org/manual/tutorial/isolate-sequence-of-operations/

+0

非常聰明!謝謝 – user606521