在mongodb文档中更新和查询评级

时间:2013-08-26 17:39:13

标签: mongodb

我有mongodb collection users。 每个用户都有一个名为rating的字段,介于1和5之间。这意味着当用户对另一个用户进行投票时,他'给'他的投票是1到5之间的数字。我在存储这些数据时遇到问题在mongo文档中因为我必须通过rating字段查询用户集合,我必须以原子方式更新它...

  1. 如果我可以使用votes_number运算符更新$inc但我无法存储评分和投票数,但我无法原子设置rating = ((rating*votes) + vote_val)/(votes+1)

  2. 我可以在文档中保留投票数和投票数,并使用$inc进行更新,但后来我无法查询WHERE votes_sum/votes_num > 3 ...

  3. 这个问题有解决办法吗?

1 个答案:

答案 0 :(得分:2)

您可以使用上面的选项二,然后将其与缓存的结果字段组合。您可以设置数据流,以便在更新时使用过滤谓词使结果字段与文档的其余部分保持一致。

第一步是在您的架构中添加一个新字段,该字段将是您的缓存评级字段。这将允许您执行范围查询,而无需进行动态划分。你遇到的问题是你无法原子地增加votes_sum& votes_num fields AND在相同的原子操作中设置缓存的评级字段。所以这就是你做的。

1)以原子方式递增votes_sum和voting_num字段
2)抓住_id,votes_sum& vote_num用于更新的文件
3)更新评级,但作为过滤谓词的一部分,包括_id,预期的votes_sum和预期的votes_num字段。

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/