我想实现一个简单的会话功能,其中每个会话在两个用户之间有一组消息。我的问题是,如果我有一条从消息到对话的引用,我是否应该以其他方式引用。
现在,每封邮件都有conversationId
。要检索属于某个对话的所有邮件,我应该Message.find({conversationId: ..})
。如果我在对话对象中存储了一组消息,我可以conversation.messages
。
惯例是哪种方式?
答案 0 :(得分:1)
这完全取决于使用模式。首先,您规范化:1个会话有很多消息,1个消息属于1个会话。这意味着您在对话和消息之间建立了1对多(1:M)的关系。
在1:M关系中,SQL标准是分配" 1"作为每个" M"的外键。因此,每条消息都会有conversationId。
在Mongo中,您可以选择通过数组执行相反的操作。就像你说的,你可以在对话中存储一组messageIds。这变得相当混乱,因为对于每条新消息,您都必须编辑对话文档。您基本上将对DB和DB的写入加倍。保持2个写入同步完全在你身上(例如,如果用户删除了一条消息并且未从会话中删除它,该怎么办?)。
在Mongo中,您还必须考虑1:M和1:F(1对少)之间的差异。很多时候,嵌套1:F关系是有利的,即制作" F" " 1"的子域。有一个限制:每个文档不能超过16MB(这可能会在未来的版本中提升)。嵌套subdocs的优点是你有原子事务,因为它是所有相同的doc,更不用说pub / sub中的订阅更容易了。这可能有用,但如果您与过去4年一直在进行的20位朋友进行了群聊,您可能必须变得聪明(限制它,开始新的对话等等)。 )
嵌套将是我的建议,尽管你为每条消息分配一个conversationId的起源也是有效的(确保索引!)。