【问题标题】:mongodb limit in the embedded document嵌入文档中的mongodb限制
【发布时间】:2012-01-17 03:39:11
【问题描述】:

我需要创建一个消息系统,一个人可以在其中与许多用户进行对话。 例如,我开始与 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为例)并且他们没有向您展示所有对话,他们向您展示了一部分,然后他们向您展示了其他消息。 在其他情况下跳过,限制解决了这种情况,但是我该怎么做呢?

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

【问题讨论】:

    标签: mongodb document mongodb-php


    【解决方案1】:

    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
    

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

    【讨论】:

    • 没问题。如果我的回复对您的问题有所帮助,请将答案标记为已选择。这会给我加分,让用户在未来更有可能回答你的问题:)
    【解决方案2】:

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

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

    我的建议是:

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

    结果:

    • 您必须将所有消息写入两次。但是分成单独的集合,这是正常的。
    • 当您想要显示您的对话时,您只需从natural sort order 的一个集合中选择所有数据,这非常快。
    • 您的封顶收藏将自动存储最后的消息并删除旧的。
    • 您可以通过查询主消息集合在用户请求中显示较旧的消息。

    【讨论】:

    • @SalvadorDali 你不必担心大量的收藏。选择正确的速度非常快,并且这个数字没有理论上的限制。但你是对的,很难支持如此大量的收藏。现在我将建议使用一个巨大的上限集合,并在对话中添加额外的索引。在这种情况下会有两个额外的问题:一些旧的对话将在没有任何先前消息的情况下加载,并且在上限集合中拥有索引不是很好。
    • 如果将它们分离到另一个数据库中,处理大量集合可能会更容易。说到文件大小。拥有一堆大小约为 1MB 的巨大文档甚至都不好。因为它会降低驱动性能、复制和分片性能。就我个人而言,我永远不会将对话存储在一个文档中。有很多可能的问题:搜索消息,共享或复制单个消息等。
    猜你喜欢
    • 1970-01-01
    • 2018-08-21
    • 1970-01-01
    • 2011-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-09
    相关资源
    最近更新 更多