使用外键查询MongoDB

3
我有两个集合:
用户(USERS):
{ id:"aaaaaa" age:19 , sex:"f" }
{ id:"bbbbbb" age:30 , sex:"m" }
评论(REVIEWS):
{ id:777777 , user_id:"aaaaaa" , text:"some review data" }
{ id:888888 , user_id:"aaaaaa" , text:"some review data" }
{ id:999999 , user_id:"bbbbbb" , text:"some review data" }
我想查找所有性别为“f”且年龄大于18岁的评论(REVIEWS)。由于评论(REVIEWS)集合非常庞大,因此不希望嵌套查询。
2个回答

2

您应该将用户数据包含在每个评论中(即反规范化):

{ id:777777 , user: { id:"aaaaaa", age:19 , sex:"f" } , text:"some review data" }
{ id:888888 , user: { id:"aaaaaa", age:19 , sex:"f" } , text:"some other review data" }
{ id:999999 , user: { id:"bbbbbb", age:20 , sex:"m" } , text:"mome review data" }

在这里,阅读一下MongoDB数据建模和Rails的链接

关于去规范化的说明

对于那些关注关系型数据库的纯粹主义者而言,他们可能已经感到有些不安了,似乎我们正在违反某些普遍法则。但是让我们记住,MongoDB集合并不等同于关系表;每个集合都有其独特的设计目标。规范化的表提供了一个原子的、隔离的数据块。然而,一个文档更接近于作为整体的对象。在社交新闻网站的情况下,可以认为用户名是发布的故事所固有的。

那么对于用户名的更新呢?的确,这样的更新会很昂贵;但幸运的是,在这种情况下,它们会很少发生。通过去规范化实现的读取节省肯定会超过偶尔更新的成本。不幸的是,这不是硬性规定:最终,开发人员必须评估其应用程序的适当规范化级别。


如果用户数据发生更改,这个模型将要求我们手动更新每个评论的所有嵌套用户数据。如果我们在嵌套数据上建立索引,索引也必须重新构建。对于拥有数千条评论的用户,任何用户数据的更改都需要更新数千条记录。谢谢。 - Om Solari
没错,这就是它的缺点。如果你选择这条路,每次更新用户信息时,你都需要更新其他记录。因此,你必须决定在权衡的哪一方:大量更新或大量查询。这完全取决于你更多地做哪个操作。 - Herman Junge
1
你认为用户数据的哪一部分会发生变化?性别?不太可能。年龄?你是想存储他们当前的年龄还是创建评论时的年龄? - Asya Kamsky

1

除非您使用搜索属性对REVIEWS集合进行去规范化,否则MongoDB不支持在单个查询中查询另一个集合。请参阅此帖子。


DBREF怎么样?它不算查询另一个集合吗? - Om Solari
你仍然只能通过 $id 或 _id 进行查询。对于其他字段,您需要执行另一个查询。此外,DBRef 是在客户端解析的,并且根据您的驱动程序,可能支持自动填充,也可能不支持。这意味着,无论如何,您最终都需要执行另一个查询。 - user1480400

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接