2011-12-09 153 views
7

我需要创建一个消息系统,其中一个人可以与许多用户进行对话。 例如,我开始与用户2,用户3和用户4交谈,以便他们中的任何人都可以看到整个对话,并且如果在任何时间点对话都不是私密的,则任何参与者都可以将任何其他人添加到对话中。嵌入式文档中的mongodb限制

这是我的想法如何做到这一点。 我正在使用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为例),他们没有向你显示所有的对话,他们向你展示了一部分之后他们会向您显示其他消息。 在其他情况下跳过,限制解决这个问题,但我怎么能在这里做到这一点?

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

回答

13

The MongoDB docs解释如何选择一个数组元素的子范围。

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 

您可以使用此技术仅选择与您的用户界面相关的消息。但是,我不确定这是一个很好的模式设计。您可能需要考虑从“已存档”消息中分离出“可见”消息。这可能会使查询变得更简单/更快。

+0

没问题。如果我的回复帮助您解决了问题,请将答案标记为选中状态。这会给我点数,并让用户更有可能在未来回答你的问题:) – jmacinnes

+0

非常有帮助谢谢! – webmaster

1

有,如果您的通话将有很多很多的邮件警告:

  1. 你会发现在切片的消息阵列显著性能下降的MongoDB的将不加载所有这些,返回驱动程序之前,将切片列表只。
  2. 这种方法可能会达到文档大小限制(现在为16MB)。

我的建议是:

  1. 使用两个集合:一个用于通话的工具和其他的消息。
  2. 在对话消息中使用dbref(将此字段与消息时间戳索引,以便能够根据用户请求选择较早的范围)。
  3. 附加使用单独capped collection为每个对话。

    • 您将有两次写的所有消息:如果你建立了像“conversation_”

结果将很容易通过名称来找到它。但是分开收集这是正常的。

  • 当您想要显示对话时,您只需要从natural sort order中的一个集合中选择所有数据,这些数据非常快。
  • 您的加盖集合将自动存储最后的消息并删除旧的。
  • 您可以通过查询主要消息集合,在用户请求上显示较早的消息。
  • +0

    @SalvadorDali你不需要害怕大量的藏品。选择正确的一个是非常快的,没有理论上的限制。但是你是对的,很难支持这么多的收藏。现在我要建议使用一个带有额外索引的巨大封顶集合来对话。在这种情况下还会有两个额外的问题:一些旧的对话将在没有任何先前的消息的情况下加载,并且在加盖集合中具有索引并不是很好。 – lig

    +0

    可能会更容易处理大量的集合,如果他们将被分离到另一个分贝。 说说文档大小。有一堆大小约为1MB的大文件甚至不好。因为它会降低驱动程序性能,复制和分片性能。我个人决不会将对话存储在一个文档中。有很多可能的问题:搜索消息,共享或复制单个消息等。 – lig

    +1

    4年后...这是一个多么可怕的答案... – lig