维护另一个集合中集合的总计数

时间:2013-08-14 19:56:27

标签: mongodb

我得到了两个实体的简单场景:post;颠簸(即upvote)。

帖子示例:

{_id: 'happy_days', 'title': 'Happy days', text: '...', bumps: 2}

凹凸的例子:

{_id: {user: 'jimmy', post: 'happy_days'}}
{_id: {user: 'hans', post: 'happy_days'}}

问题:在所有情况下(以及失败),如何在帖子中保持正确的bumps计数?

到目前为止我提出的方法是:

  • 碰撞,升起并检查是否存在。仅在插入时,增加bumps次。
  • 要取消,删除并检查是否存在。仅在删除时,减少bumps次。

如果应用程序在两个操作系统之间崩溃,并且纠正颠簸统计数据的唯一方法是查询凹凸集合中的所有文档并离线重新计算所有内容(即无法知道哪个帖子的错误计数不正确),则上述操作失败。

3 个答案:

答案 0 :(得分:1)

作为在多个位置更新数据的替代方法(对于读取性能,可能是最好的,但正如您所注意到的那样会使更新复杂化),可能值得考虑将uid的凹凸存储在数组中(此处称为bump_uids) )直接在帖子上,并在需要时使用聚合框架计算颠簸;

> db.test.aggregate( [ { $match: { _id:'happy_days' } },
                       { $project: { bump_uids: 1 } },
                       { $unwind: '$bump_uids' }, 
                       { $group: {_id:'$_id', bumps: { $sum:1 } } } ] )

>>> { "result" : [ { "_id" : "happy_days", "bumps" : 3 } ], "ok" : 1 }

答案 1 :(得分:1)

我建议你坚持你已经拥有的东西。如果您的两个操作之间存在故障转移/连接问题,则可能发生的最糟糕情况是您的计数错误。所以呢?这不是世界末日,如果碰撞计数为812或813,则没有人会太在意。无论如何,您可以通过运行聚合查询来检查每个帖子有多少个碰撞来重新计算计数<强烈>如果出现问题。拥抱最终的一致性!

答案 2 :(得分:0)

由于MongoDB还不支持触发器(https://jira.mongodb.org/browse/SERVER-124),因此必须采用应用程序逻辑的粗略方法。

作为一个简短的例子:

db.follower.insert({fromId:u,toId:c});
db.user.update({_id:u},{$inc:{totalFollowing:1}});
db.user.update({_id:c},{$inc:{totalFollowers:1}});

是的,它不是原子等等,但它是这样做的方式。实际上很多更新计数器都是这样的,无论是否在MongoDB中。