基于MongoDB的好友消息动态的实现思路

xuemoyao 2011-10-18

引用说明:原文来自于http://nightsailer.com/2010/02/21/675.html,为了方便本人阅读,文本格式略有调整。

基于MongoDB的好友消息动态的实现思路

好友动态是SNS最常见的功能。在设计“视觉中国原创榜”的好友动态时,也遇到如何实现的问题。和普通的SNS不同,

视觉中国原创榜用户不仅仅关注好友的动态,而且也要关注自己的作品和自己曾经关注过的作品的动态。

这样,就需要给用户分别push3种不同的动态:我的作品的动态,我关注过的作品(包括收藏过,评论过,评分过)的动态,

以及我关注的人(followed)的动态,未来还有好友的动态。这些动态,用户都应该可以取消关注。如何实现?

使用传统的数据库会面临很多问题,比如如何sharding。 幸运的是,我们用的MongoDB,这给我们解决问题带来了极大的方便。

首先,对每个用户,分别设计以下 collection

//by nightsailer.com
activity_streaming.feed, 属性分别为:
$schema = array(
_id, 用户id
followed_art => array(), 用户关注的作品id列表
followed_people=>array(), 用户关注的人id列表
my_art => array() 用户的作品id 列表
)
//by nightsailer.com
activity_stream.user:
_id
type=> 动态steam的类型(我关注的作品,我的作品,我关注的人)
stream_target => 对应动态stream的对象(作品id,人id)
stream => array() FIFO数组,存放activity的DBRef
time => int 最后一次activity的时间戳
activity_stream.site
_id uuid
type: 动态类型
data: hash 动态数据
time
 

activity_stream.queue

同activity_stream.site

存放待处理的动态队列

我们使用异步处理方式,按照以下流程:

1.当用户某些动作产生一个事件后,将事件push到activity_stream.queue,通知worker进行处理

2.worker被唤醒,从activity_stream.queue中提取未处理的事件。

3.worker将事件放入activity_stream.site,作为全站动态广播

4.worker从activity_streaming.feed中反向查找事件的作品或作者是否有对应的人,如果有,则将此事件id

push到activity_stream.user的对应fifo数组中。

(这是MongoDB最兴奋的地方,可以直接查询数组中的值,只要对数组进行索引)

这样,用户可以:

- 从activity_stream.user 中删除某个事件

-从activity_stream.feed中删除某个关注的对象(实现类似忽略这个人的动态,忽略这个作品的动态等等)

-当用户关注好友后,将其加入activity_stream.feed

-当用户上传作品后,将作品加入activity_stream.feed

- 当用收藏、评分、评论后,将其作品加入activity_stream.feed

相关推荐