2013-02-04 36 views
3

我有一个mongodb数据库,其中有2个集合。 postsusersmongo db - 用于在webapp中实现相似功能的模式

帖子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 ..]} 

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

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

回答

2

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

您可以使用类似字段获得用户喜欢的帖子。如果你有类似领域的索引,性能也会很好。

唯一的缺点是使用这种方法后对象的大小根据数组的长度而变化。 Mongo在处理这些数据结构方面并不是很擅长,所以如果你有数千人喜欢留言,所有的id可能会降低查询的性能,但是在一般的帖子中并没有那么多人喜欢,系统将工作正常,我相信。您可能会认为对某个帖子的喜爱ID数量有限制(例如,保留最后的1000个用户ID),以确保文档的大小不会显着增加。

6

我个人不会在这里找一个类似的数组。

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

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

$unwind是一个存储器内操作,特别是如果各使用者就座于至少1000个喜欢(50x1000已经推动内存限制$unwind和后$group$sort,其可以是对许多用户的间隔聚合缓慢,其内存限制为系统内存的10%)。总而言之,所有的聚合框架都不会使用高级方法来查询这些喜欢的东西。

MongoDB中可以很容易地evne存储这种结构虽然在其gorwing形式,因为子文档就像是每个条目,所以你可以只使用2种尺寸(http://docs.mongodb.org/manual/reference/command/collMod/#usePowerOf2Sizes)分配的功率来弥补你通常会得到的问题,也许12个字节(碎片)与使用该结构。

所以考虑这个我会保持喜欢在一个单独的集合。确实,你会失去在用户文档中容纳喜欢的单一往返标记,但我相信我上面提到的是值得的。

+0

你可以告诉我,我应该有独立的像收集...吗? – ravisuhag

+1

@ravisuhag由于用户可以拥有大量的喜欢,我可能会把这些喜欢的自己放入一个单独的{'_id :(),user_id:(),media_id:(),collection:(),date_liked :()}“收藏”字段将让您喜欢多个媒体项目,即墙壁帖子和视频。 – Sammaye

4

问你自己的重要问题是你需要什么不同的方式来获取这些数据?

可以在第一种情况下询问用户谁喜欢特定的页面,user.find({"likes":postId})和第二种情况下的相反查询。但这是个好主意吗?你想要避免在MongoDB中持续增长的文档加上你可能不想知道特定用户全部他们喜欢的页面,以及特定页面全部喜欢它的用户。

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

很少有可能在不知道用例(即读写模式)和它周围的需求的情况下在MongoDB中设计“理想”模式。

相关问题