7

我需要创建一个消息系统,一个人可以在其中与许多用户进行对话。例如,我开始与 user2、user3 和 user4 交谈,因此他们中的任何人都可以看到整个对话,如果对话在任何时候都不是私密的,任何参与者都可以将任何其他人添加到对话中。

这是我的想法如何做到这一点。我正在使用 Mongo,我的想法是使用对话框作为实例而不是消息。

架构如下所示:

{
_id : ...., // dialog Id
'private' : 0 // is the conversation private
'participants' : [1, 3, 5, 6], //people who are in the conversation
'msgs' :[
  {
   'mid' : ...// id of a message
   'pid': 1, // person who wrote a message
   'msg' : 'tafasd' //message
  },
  ....
  {
   'mid' : ...// id of a message
   'pid': 1, // person who wrote a message
   'msg' : 'tafasd' //message
  }
]
}

我可以看到这种方法的一些优点——在一个大数据库中,很容易找到一些特定对话的消息。- 很容易将人添加到对话中。

但这里有一个问题,我找不到解决方案:对话变得太长(以Skype为例)并且他们没有向您展示所有对话,他们向您展示了一部分,然后他们展示了你额外的消息。在其他情况下跳过,限制解决了这种情况,但我该怎么做呢?

如果这是不可能的,你有什么建议?

4

2 回答 2

16

MongoDB 文档解释了如何选择数组元素的子范围。

db.dialogs.find({"_id": [dialogId]}, {msgs:{$slice: 5}}) // first 5 comments
db.dialogs.find({"_id": [dialogId]}, {msgs:{$slice: -5}}) // last 5 comments
db.dialogs.find({"_id": [dialogId]}, {msgs:{$slice: [20, 10]}}) // skip 20, limit 10
db.dialogs.find({"_id": [dialogId]}, {msgs:{$slice: [-20, 10]}}) // 20 from end, limit 10

您可以使用此技术仅选择与您的 UI 相关的消息。但是,我不确定这是一个好的架构设计。您可能需要考虑从“归档”消息中分离出“可见”消息。它可能会使查询更容易/更快。

于 2011-12-09T22:36:06.527 回答
3

如果您的对话将包含许多信息,则需要注意:

  1. 您会注意到切片消息数组的性能显着降低,因为 mongodb 会加载所有消息数组并在仅返回驱动程序之前对列表进行切片。
  2. 这种方法可能会达到文档大小限制(目前为 16MB)。

我的建议是:

  1. 使用两个集合:一个用于对话,另一个用于消息。
  2. 在要对话的消息中使用 dbref(使用消息时间戳索引此字段,以便能够根据用户请求选择较旧的范围)。
  3. 为每个对话额外使用单独的上限集合。如果你像“conversation_”一样构建它,很容易通过名称找到它

结果:

  • 您必须将所有消息写两次。但是分成单独的集合这是正常的。
  • 当您想显示您的对话时,您只需以自然排序顺序从一个集合中选择所有数据,这非常快。
  • 您的封顶收藏将自动存储最后的消息并删除旧的。
  • 您可以通过查询主消息集合在用户请求中显示较旧的消息。
于 2011-12-12T11:34:31.200 回答