Javascript 了解MongoDB中的多对多关系以及如何取消对集合的引用

Javascript 了解MongoDB中的多对多关系以及如何取消对集合的引用,javascript,mongodb,mongoose,mean-stack,Javascript,Mongodb,Mongoose,Mean Stack,我花了一些时间研究MongoDB替代方案,以实现多对多关系,包括一些stackoverflow文章(和)和幻灯片 我正在使用MEAN stack创建一个应用程序,并试图确认我的模式设置和取消引用对象集合的最佳实践 我在用户和会议之间有一个基本的多对多关系(想想为用户安排会议,其中一个用户可以参加多个会议,而一个会议包含多个用户) 考虑到我的用例,我认为最好使用引用而不是嵌入。我相信(从我所读到的)只有当我的会议有一个会议所独有的用户时,使用嵌入才更好。在我的例子中,这些用户在会议中共享。此外,尽

我花了一些时间研究MongoDB替代方案,以实现多对多关系,包括一些stackoverflow文章(和)和幻灯片

我正在使用MEAN stack创建一个应用程序,并试图确认我的模式设置和取消引用对象集合的最佳实践

我在用户和会议之间有一个基本的多对多关系(想想为用户安排会议,其中一个用户可以参加多个会议,而一个会议包含多个用户)

考虑到我的用例,我认为最好使用引用而不是嵌入。我相信(从我所读到的)只有当我的会议有一个会议所独有的用户时,使用嵌入才更好。在我的例子中,这些用户在会议中共享。此外,尽管更新用户的频率很低(例如,更改用户名、密码),但我仍然觉得使用推荐信感觉不错——尽管我愿意听取意见

假设我使用了引用,我有以下(简化的)模式:

首先,您会注意到我在用户中没有会议的集合。我决定不添加此集合,因为我相信我可以使用MongoDB查找的功能来获取与特定用户相关的所有会议,即

db.meetings.find({users:ObjectId('x123')});
当然,我需要添加一些索引


现在,如果我希望在特定会议上尊重我的用户,我该怎么做?对于那些理解rails并了解两者之间差异的人,我正在寻找一个类似的概念。我知道我们在MongoDB中没有处理连接,但对于我来说,为了从会议中取消对users集合的引用以获取用户的名字和姓氏,我需要循环遍历id集合并执行某种类型的db.users.find()对于每个id。我假设我可以进行一些简单的MongoDB调用,以使其以性能的方式实现。

有关MongoDB中模式设计的讨论,请参阅MongoDB博客上的以下帖子:


特别是,看看示例JavaScript代码,它向您展示了如何进行应用程序级连接。

如果您在特定会议中拥有所有用户的id,您只需对用户集合执行一次查找,即可获得他们的名称:db.users.find({id:{$In:},{firstName:1,lastName:1})。为什么不将用户的名字和姓氏存储在会议集合的用户数组中?谢谢。因此,听起来我必须做一个单独的(单个)查询才能让用户使用$in操作——我想这很好,尽管我想知道是否可以将两个查询合并为一个(获取会议和用户的名字和姓氏)?我之所以不只是存储名字和姓氏,是因为我必须在用户更改姓名时更新这些名字。我想这是一个不错的折衷方案,意味着我应该存储这些信息并处理罕见的情况。确切地说,为什么要针对可能发生的事情进行优化?另外,你真的需要在已经发生的会议上更新一个人的姓名吗?我认为,如果他们以乔·斯莫伊的身份出席会议,那就不应该在事后改变,因为现在他被称为乔·多伊。。。即使你真的想改变它,它也是一个单一的“多”更新。谢谢你,这是一套很棒的文章。因此,Mongoose的populate()基本上实现了数据的“应用程序级连接”/“取消引用”。对吗?这正是populate()的功能。我建议根据您在文章中学到的内容重新阅读本页。文档中没有显示的是查询的实际实现方式。由于查询的exec在populate函数之后,我假设mongoose正在优化查询,可能是将查询优化为单个查询,而不是多个查询,当然不是n+1。在传统的rdbms中,“填充”函数应该只进行一次连接。由于mongodb没有连接,我假设populate在二次查询中执行$in子句(如您的示例),而不是以某种方式将主表和集合的检索组合到单个查询中。我对Mongoose了解不多。populate()的定义如下:
db.meetings.find({users:ObjectId('x123')});