我正在尝试为mongodb
中的聊天应用程序构建架构。我有两种类型的用户模型-Producer
和Consumer
。生产者和消费者可以互相交谈。我的最终目标是为所有生产者和消费者获取所有对话,并将其显示在列表中,就像所有消息传递应用程序(例如Facebook)一样。
这是我想出的schema
:
Producer: {
_id: 123,
'name': "Sam"
}
Consumer:{
_id: 456,
name: "Mark"
}
Conversation: {
_id: 321,
producerId: 123,
consumerId: 456,
lastMessageId: 1111,
lastMessageDate: 7/7/2018
}
Message: {
_id: 1111,
conversationId: 321,
body: 'Hi'
}
现在我想说说山姆的所有建议。我想像在Facebook上那样在列表中显示它们,并用 每个消费者并根据时间排序。 我想我需要对此进行以下查询:
1)获取所有以lastMessageDate排序的生产者ID为123
的会话。
然后,我可以显示所有对话的列表。
2)如果我想知道对话中的所有消息,请在Message上进行查询,并获取所有sessionId为321
的消息
现在,在这里,对于每个新的message
,我还需要每次使用新的messageId和日期更新conversation
。这是正确的进行方法,并且考虑到所涉及的查询数量是否是最佳方法?有没有更好的方法可以继续进行下去?任何帮助将不胜感激。
答案 0 :(得分:2)
设计: 我不会说这很糟糕。根据您描述的情况,它实际上非常好。最后消息日期和ID的这种非规范化非常好,特别是如果您计划一个包含所有会话列表的视图-您在同一查询中具有最后消息日期。如果适用于此视图,甚至可以更进一步并添加最后一条消息文本。
您可以在MongoDB博客(第1,2和3部分)上阅读有关反规范化(通常是模式建模)的优缺点的更多信息。它不是那么新鲜,但不是过时的。
此外,如果此类多文档更新可能会因某些不一致而使您感到恐惧,那么MongoDB v4会让您感到困惑transactions。
查询: 一方面,您可以涉及多个查询,而且一点也不差(特别是当很少有人可以轻松访问它们(例如生产者或消费者数据)时)。另一方面,如果需要,您可以使用aggregations一次获取所有这些东西。