6

我有一个 mongodb 数据库,其中有 2 个集合。postsusers

帖子json结构就像

{title:"Title", content:"content goes here", postedby: "userid"}

用户就像

{username:"", name:""}

现在我需要实现一个类似的功能,用户喜欢这些帖子。

解决方案 1

我可以在用户中放置一个内部数组,例如

{username:"", name:"", likes:[postid1,postid2..]}

这里的问题是它很容易查询用户喜欢的帖子。但是很难得到喜欢文章的人。

解决方案 2

我可以在帖子中放置一个内部数组,例如

{title:"Title", content:"content goes here", postedby: "userid", like:[userid1,userid2 ..]}

这里的问题是很容易获得喜欢文章的人。但很难查询用户喜欢的帖子。

我该如何解决这个问题?目前我正在考虑两种方式。就像在两个集合中保留内部数组一样。我知道我保留了冗余数据,这是解决此问题的最佳方法吗?

4

3 回答 3

10

我个人不会在这里选择类似的数组。

喜欢太多帖子的人喜欢失去控制是很常见的;以至于这可能会阻碍您可以存储在该文档中的顶级用户数据量。

您还必须在这里考虑您的查询模式。您很可能希望对多个用户的点赞数进行某种图形聚合。目前要动态地做这样的事情,你必须使用聚合框架:http ://docs.mongodb.org/manual/applications/aggregation/ (预聚合报告:http ://docs.mongodb.org/manual/use- case/pre-aggregated-reports/在这里也是一个有用的工具,但我会跳过它)使用$unwind.

$unwind是一种内存中操作,对于许多用户的远距离聚合可能会很慢,特别是如果每​​个用户至少有 1000 个喜欢(50x1000 已经在推动内存限制$unwind和 post$group $sort的内存限制为 10%系统内存)。总而言之,聚合框架不会是查询这些喜欢的性能方法。

MongoDB 可以很容易地存储这个结构,即使是在它的 gorwing 形式中,因为每个条目的子文档可能是 12 个字节,所以你可以使用 2 个大小的幂(http://docs.mongodb.org/manual/reference/command/ collMod/#usePowerOf2Sizes)分配以解决使用该结构通常会遇到的问题(碎片化)。

所以考虑到这一点,我会把喜欢的东西放在一个单独的集合中。确实,您将失去用户文档中包含喜欢的单次往返表示,但我相信我上面所说的值得付出代价。

于 2013-02-04T09:50:42.800 回答
5

要问自己的一个重要问题是获取这些数据需要哪些不同的方法?

可以在第一种情况下查询喜欢特定页面的用户user.find({"likes":postId}),在第二种情况下查询与该页面相反的查询。但这是个好主意吗?您希望避免在 MongoDB 中不断增长的文档,而且您可能不想知道特定用户的所有他们喜欢的页面,以及特定页面的所有用户喜欢它。

那么如何将喜欢保存在他们自己的集合中,并且只在用户和页面集合中保留聚合(即计数)?您还可以选择在页面中保留最近的“N”个赞,或者对您的应用程序及其性能最有用的任何其他内容。

在不了解用例(即读写模式)以及围绕它的需求的情况下,很少有可能在 MongoDB 中设计“理想”模式。

于 2013-02-04T20:19:37.140 回答
4

我认为仅将喜欢的数组保留在 post 文档中就足够了。

您可以使用like 字段获取用户喜欢的帖子。如果您在类似字段上有索引,性能也会很好。

唯一的缺点是,使用这种方法,post 对象的大小会根据类似数组的长度而变化。Mongo 不是很擅长处理这类数据结构,所以如果你对一个帖子有数千个赞,保留所有 id 可能会降低查询性能,但一般来说帖子没有那么多赞,总的来说你的我相信系统会正常工作。您可能会考虑限制帖子的点赞 id 数量(例如,保留最后 1000 个用户 id)以确保文档的大小不会过度增长。

于 2013-02-04T08:49:58.067 回答