mongo db - 用于在webapp中实现类似功能的模式

mit*_*esh 5 database mongodb nosql

我有一个mongodb数据库,我有2个收藏.postsusers.

帖子json结构就像

{title:"Title", content:"content goes here", postedby: "userid"}
Run Code Online (Sandbox Code Playgroud)

和用户一样

{username:"", name:""}
Run Code Online (Sandbox Code Playgroud)

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

解决方案1

我可以在用户中添加一个内部数组

{username:"", name:"", likes:[postid1,postid2..]}
Run Code Online (Sandbox Code Playgroud)

这里的问题是它易于查询用户喜欢的帖子.但很难找到喜欢文章的人.

解决方案2

我可以把内部数组放在帖子中

{title:"Title", content:"content goes here", postedby: "userid", like:[userid1,userid2 ..]}
Run Code Online (Sandbox Code Playgroud)

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

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

Sam*_*aye 8

我个人不会在这里找一个类似的阵列.

喜欢失去控制权的人太喜欢太多的帖子了; 到这可能会阻碍您可以存储在该文档中的顶级用户数据量.

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

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

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

所以考虑到这一点,我会把喜欢留在一个单独的集合中 确实,您将失去在用户文档中包含喜欢的单一往返符号,但我相信我上面所说的是值得的.


Asy*_*sky 5

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

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

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

这是几乎不可能设计出MongoDB中的"理想"模式,而不知道使用情况下(即读写模式),什么周围的要求是.


cub*_*buk 4

我认为只需将喜欢的数组保留在帖子文档中就足够了。

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

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