0

我得到了两个实体的简单场景:发布;颠簸(即赞成)。

帖子示例:

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

颠簸示例:

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

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

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

  • 碰撞,插入并检查是否存在。仅当插入时,才增加bumps计数。
  • 要取消凹凸,删除并检查是否存在。仅当删除时,减少bumps计数。

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

4

3 回答 3

1

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

> 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 }
于 2013-08-14T20:39:14.047 回答
1

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

于 2013-08-15T08:52:33.977 回答
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 中,都有许多这样的更新计数器。

于 2013-08-14T20:29:14.563 回答