繁体   English   中英

MongoDb有很多大关系

[英]MongoDb many to many with big relations

我在Stackoverflow上阅读了很多文档和示例,但是我不确定自己的结论,因此这就是我寻求帮助的原因。

想象一下,我们有一个电影集和一个用户集,我们想知道,哪些用户看过电影,哪些电影看过用户。

在MongoDb中设计此方法的一种方法是:

用户:

{
"name":"User1",
"films":[filmId1, filmId2, filmId3, filmId4] //ObjectIds from Films
}

电影:

{
"name": "The incredible MongoDb Developer",
"watched_by": [userId1, userId2, userId3] //ObjectsIds from User
}

好的,如果用户/电影的数量很少,这可能会起作用,但是例如,如果我们希望一部电影将有80万用户,则阵列的大小将接近:800k * 12字节〜9.5MB,这几乎等于BSON文件最大为16MB。

在这种情况下,除了典型的关系世界方式之外,还有其他方法可以为关系创建中间集合吗?

另外,我不知道与经典的关系方式相比,读取和解析大约10MB的JSON是否会有更好的性能。

谢谢

对于电影,如果包括观众,您可能最终会达到BSON文档16MB大小限制 ,正如您正确指出的那样。

根据您的用例,将用户观看过的电影放入阵列是一种可行的方法。 尤其是如果您想与属性建立关系(例如日期和查看地点),则执行更新和统计分析的性能会降低(您需要先$unwind文档,随后的$matches变得更加昂贵,没什么)。

如果您的关系具有属性或可能具有属性,那么我将按照您所说的经典关系方法去处理,因为它可以很好地解决您最可能的用例,并且可以根据我的经验提供更高的性能:

给定具有以下结构的集合

 {
   _id: someObjectId,
   date: ISODate("2016-05-05T03:42:00Z"),
   movie: "nameOfMovie",
   user: "username"
 }

您随时可以轻松回答以下示例问题:

  1. 对于给定的用户,他在过去3个月中按日期降序看了哪些电影?

     db.views.aggregate([ {$match:{user:userName, date:{$gte:threeMonthAgo}}}, {$sort:{date:-1}}, {$group:{_id:"$user",viewed:{$push:{movie:"$movie",date:"$date"}}}} ]) 

    或者,如果您可以使用迭代器,则可以使用以下方法更轻松:

     db.views.find({user:username, date:{$get:threeMonthAgo}}).sort({date:-1}) 
  2. 对于给定的电影,今年5月30日有多少用户看过电影?

     db.views.aggregate([ {$match:{ movie:movieName, date{ $gte:ISODate("2016-05-30T00:00:00"), $lt:ISODate("2016-05-31T00:00:00")} }}, {$group:{ _id: "$movie", views: {$sum:1} }} ]) 

    我在结果上使用聚合而不是.count()的原因是SERVER-3645

  3. 对于给定的电影,请向所有看过该电影的用户显示。

     db.views.find({movie:movieName},{_id:0,user:1}) 

有一点需要注意:由于我们分别使用了用户名和电影名称,因此我们不需要JOIN(或类似名称),这应该可以给我们带来良好的性能。 另外,添加条目时,我们不必执行昂贵的更新操作。 无需更新,我们只需插入数据即可。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM