基于图表的新闻Feed&活动日志

时间:2015-09-30 15:28:12

标签: database-design graph neo4j cypher news-feed

几天来,我一直致力于使用Neo4j图形数据库开发新闻源,并通过各种方式来寻找包含活动日志(类似于Facebook)的方法,以跟踪每个用户的操作。

例如,User1向User2发送了一个朋友请求(在Cypher中会转换为类似的内容):

MATCH
    (me:User {username: 'john.snow@gmail.com'}), 
    (friend:User {username: 'arya.stark@gmail.com'})

WHERE 
    NOT (me)-[:FRIENDSHIP_UPDATE]-(:FriendshipStatus)-[:FRIENDSHIP_UPDATE]-(friend)

CREATE
    (me)-[:FRIENDSHIP_UPDATE]-(friendshipStatus:FriendshipStatus {status: 0})-[:FRIENDSHIP_UPDATE]->(friend)

RETURN
    me,
    friendshipStatus,
    friend

到目前为止,非常基本的东西,只需创建2个关系和1个节点,其中包含有关其友谊的所有信息。

检索传出和传入事件也非常简单:

MATCH
    (me:User {username: 'john.snow@gmail.com'})-[actionName]->(actionData)-[]->(friend:User)

RETURN
    me,
    type(actionName) AS actionName,
    actionData,
    friend

UNION MATCH
    (me:User)<-[actionName]-(actionData)<-[]-(friend:User)

RETURN
    me,
    type(actionName) AS actionName,
    actionData,
    friend

但是,假设User2拒绝User1好友请求,最终会删除他们之间的整个关系。没问题...对于一个简单的通知面板(比如“你有一个朋友请求”,另一个取消了朋友请求,“oups,没有朋友请求”)。所以,没有历史。

就像我说的那样,我打算做像Facebook活动日志这样的事情。

> You liked [User]'s*link to the user* [Photo]*link to the photo* at [Time].
> [User]*link to user* declined your friend request at [Time].
> You sent [User]*link to user* a friend request at [Time]

我玩弄了各种各样的方式,包括链接列表,直到今天。然后,日子将包含用户在特定日期执行或已经暴露的事件(当创建事件时,它也被推送到朋友时间线 - 请参阅第二个代码块)并保持用户之间的直接关系(友情更新,喜欢等等,因此我不必搜索所有Day节点。

编辑:忘了提及为什么我没有坚持这个特定的设计。

问题在于行动之间没有相似之处(例如,“喜欢”指向“帖子”而“友情请求”指向“用户”),这使我最终得到了多个,不需要的连接。

跟踪所有这些操作的好数据库设计是什么,即使它们被删除了?

提前谢谢。

1 个答案:

答案 0 :(得分:1)

有用的事件日志不得删除任何日志条目,并且必须可靠地返回包含原始数据的条目。实质上,日志条目是静态数据,一旦创建就不能更改。

  1. 可能最好的解决方案是维护一个单独的日志DB&#34; (可能甚至不是图形DB)所有事件的日志条目。这将保留您的&#34;实时数据&#34; DB更简单,您的日志记录机制也会更简单。
  2. 如果您想为日志条目使用相同的neo4j数据库,您可以将其保存在单独的&#34;日志子图中&#34;这与你的&#34;实时数据子图不相交&#34; (即,没有共享节点,并且&#34;日志节点&#34;和&#34;活动节点&#34;之间没有关系 - 尽管日志属性可以包含关于实时数据的标识信息)。它必须脱节的原因是因为实时数据可以随时改变(例如,节点/关系可以删除,属性可以改变等),但是日志条目仍然必须能够返回应用于的数据状态创建条目的时间。不过,这种方法可能比值得付出更多努力。