什么是良好的MongoDB文档结构,可以最有效地查询用户关注者/被关注者?

时间:2012-07-16 08:04:41

标签: mongodb documents

我一直想知道理想的文档结构,以便在各种情况下获得最大的查询效率,并且我想问一下。在这种特殊情况下,我真的不知道MongoDB在内存中的表现如何。让我给你一个假设的情景。

想象一下Twitter风格的追随者和追随者系统。在粗略地看了一眼后,主要选项似乎是:

  1. 在每个用户文档中,“关注者”数组包含对其关注的其他用户的所有文档的引用。通过在其他用户的“user.followers”数组中查找我们当前的用户来找到被关注者。主要的缺点似乎是Followee搜索的潜在查询开销。此外,对于专门针对“user.followers”内容的查询,MongoDB是否只访问用户文档中的必填字段,或者是找到整个用户文档,然后从那里查找所需的字段值并将其缓存/存储的方式是对大型用户群的查询需要更多的内存吗?

  2. 在每个用户文档中,存储“关注者”和“关注者”,以便更快地访问每个用户文档。这显然具有重复数据的缺点,即在用户B之后的用户A的条目存在于相应字段中的两个用户文档中,并且从中删除需要在另一个中的匹配删除。从技术上讲,这可能是考虑将简单删除的潜在失败点数加倍。当删除发生时,MongoDB是否仍然遭受我所听到的描述为“swiss cheesing”的内存存储数据,因此从2个字段中删除而不是1会使内存空洞问题的影响加倍?

  3. 用于存储用户关注者的单独集合,以与1-中用户文档类似的方式查询,除了显然唯一被访问的数据是关注者,因此如果用户文档包含相当多的其他数据相关对于每个用户,我们避免访问该数据。这似乎有一些关系数据库的感觉,虽然我知道在原则上并不总是一个糟糕的方法,显然如果提到的其他方法之一(或我没有考虑过)在Mongo的架构下更好我我喜欢学习!

  4. 如果有人对此有任何想法,或者想告诉我,我错过了一个非常相关且明显的文档页面,或者甚至想告诉我,我只是在愚蠢(想到解释为什么,请;))我很想听到你的消息!

2 个答案:

答案 0 :(得分:7)

这是一个典型的跟随者 - 跟随者问题,并且没有人回答它。查看此链接:

mongo db design of following and feeds, where should I embed?

实际上,如果MongoDB和SQL服务器是您唯一的选择,这种情况非常适合关系模式。但这是一种特殊的关系问题,你有双向关系。这可以通过图形数据库更好地处理:

http://forum.kohanaframework.org/discussion/10130/followers-and-following-database-design-like-twitter/p1

问题是,您可以在用户文档中保留关注者或关注者,但不能同时保留两者,以避免双重删除问题。因此,如果您必须坚持使用MongoDB,那么可以选择一种方式......(假设人们不关注/取消关注 经常出现的人),

只保留文档中的跟随者,因为当我查看我的个人资料时,我会对我关注的人感兴趣..(这就是我首先关注他们的原因,对吧?)..然后做一个像:

db.Users.find({ user_id : { $in : followees })

这将告诉所有人都关注我(说我的id是'user_id')。

我不建议反过来的另一个原因是...最多可以跟随30-40人,所以存储30-40个跟随者的用户文档应该可以存储数千个关注者的用户文档!使用文档跟随方法,您可以获得大致均匀的用户文档。在文档跟随方法中,您将获得一些非常小但一些非常庞大的文档。根据您输入的关注者数据量(如果有的话,除了follower_id),您可能要小心文档大小限制。

答案 1 :(得分:2)

鉴于它有多对多的关系,选项(2)对我来说很好看。至于匹配删除,它通常不是问题,只要你在两个文件之间有某种协调机制。

碎片通常取决于应用程序的访问模式,并且通常是大多数数据系统的问题。为了避免内部碎片,已经对mongo进行了一些重大更改。此外,如果发生碎片,还有离线压缩替代方法来修复碎片。