什么样的MongoDB文档结构可以最有效地查询用户关注者/关注者?

什么样的MongoDB文档结构可以最有效地查询用户关注者/关注者?,mongodb,documents,Mongodb,Documents,我一直在想,在各种情况下,如何使用理想的文档结构来实现最大的查询效率,我想问一个问题。事实证明,在这种特殊情况下,我并不知道MongoDB在内存中的行为。让我给你一个假设的情景 想象一个Twitter风格的追随者和追随者系统。经过公认的粗略一瞥,主要的选择似乎是: 在每个用户文档中,都有一个“followers”数组,其中包含对他们关注的其他用户的所有文档的引用。Followees是通过在其他用户的“user.followers”数组中查找我们的当前用户来找到的。主要的缺点似乎是Followee

我一直在想,在各种情况下,如何使用理想的文档结构来实现最大的查询效率,我想问一个问题。事实证明,在这种特殊情况下,我并不知道MongoDB在内存中的行为。让我给你一个假设的情景

想象一个Twitter风格的追随者和追随者系统。经过公认的粗略一瞥,主要的选择似乎是:

  • 在每个用户文档中,都有一个“followers”数组,其中包含对他们关注的其他用户的所有文档的引用。Followees是通过在其他用户的“user.followers”数组中查找我们的当前用户来找到的。主要的缺点似乎是Followee搜索的潜在查询开销。另外,对于专门针对“user.followers”内容的查询,MongoDB是否只访问用户文档中的必填字段,或者是找到了整个用户文档,然后从中查找所需的字段值,并且这种缓存/存储方式是否会导致对大量用户的查询需要更多的内存

  • 在每个用户文档中,同时存储“followers”和“followeres”,以便更快地访问每个文档。这显然有重复数据的缺点,即在相应字段的两个用户文档中都存在用户A和用户B的条目,从中删除需要在另一个字段中进行匹配的删除。从技术上讲,这可能是考虑将简单删除的潜在故障点增加一倍。MongoDB是否仍然遭受着我所听到的在删除时内存存储数据的“瑞士干酪化”的痛苦,因此从2个字段而不是1个字段中删除会使内存漏洞问题的影响加倍

  • 一个单独的集合,用于存储用户的关注者,以与1中的用户文档类似的方式查询-除了访问的唯一数据显然是关注者之外,因此如果用户文档包含与每个用户相关的大量其他数据,我们将避免访问该数据。这似乎给人一种关系数据库的感觉,虽然我知道从原则上讲,这并不总是一种糟糕的方法,但显然,如果提到的其他方法(或我没有考虑过的方法)中的一种在Mongo的体系结构下更好,我很想学习


  • 如果有人对此有任何想法,或者想告诉我我错过了某个非常相关和明显的文档页面,或者甚至想告诉我我只是太傻了(请解释一下原因),我很乐意听到你的消息

    考虑到这是一种多对多的关系,我觉得选项(2)不错。至于匹配的删除,这通常不是问题,只要两个文档之间有某种协调机制


    碎片通常取决于应用程序的访问模式,并且通常是大多数数据系统的一个问题。mongo已经做了一些重大更改,以避免内部碎片化。此外,如果出现碎片,还可以使用脱机压缩替代方法来修复碎片。

    这是一个典型的followee问题,没有人能解答。请查看此链接:



    实际上,如果MongoDB和SQL server是您唯一的选择,那么这种情况非常适合关系模式。但这是一种特殊类型的关系问题,其中存在双向关系。图形数据库可能可以更好地处理这一问题:



    问题是,您可以在用户文档中保留followers或followers,但不能同时保留二者,以避免双重删除问题。因此,如果您必须坚持MongoDB,一个出路可能是……(假设人们不经常跟随/不跟随任何人),

    在文档中只保留以下内容,因为当我查看我的个人资料时,我会对我关注的人感兴趣。。(这就是我首先遵循它们的原因,对吗?)。然后执行类似于:

    db.Users.find({user\u id:{$in:followees})


    这将告诉谁都在跟踪我(假设我的id是“user\u id”)。


    我不建议另一种方法的另一个原因是..一个人最多可以跟随30-40人,因此存储30-40个followees的用户文档与存储数千个followee的用户文档相比应该没问题!使用followee-in-document方法,在follower-in-document应用程序中,您可以获得大小大致相同的用户文档roach,你会有一些非常小但非常庞大的文档。这取决于你输入的追随者数据量(如果有,除了追随者id),您可能需要注意文档大小限制。

    您将使用什么编程语言?取决于底层驱动程序可能支持或不支持某些功能。我特别要说的是DBRefs。这是一个很好的观点,谢谢。我们最终可能会使用PHP和Node.js.Ni的混合CE!你已经涵盖了我必须说的所有要点!选项2绝对是“不”。存储你正在跟随的用户的ID是行进的方式。得到一个跟随你的用户的列表只是一个查询,并且可以被索引。参考:这也是我要考虑的方式,但是,我有点担心Mo中的“无界字段”性能问题。ngo,这可能会使这成为一个糟糕的选择。请看:你对此有什么想法?@UpTheCreek无界字段这是我遵循的ppl列表。假设这不会超过30-40个用户,与包含数千个追随者的无界字段相比,这将不是一个问题。同样,这个论点对于这种使用非常具体案例(twitter风格的followee)。我已经为几个应用程序实施了同样的策略。你从中得到的唯一主要缺点是让客户知道他们是否喜欢/