因为它真的是not possible to return a single embedded document(尚未),什么是良好的数据库设计替代方案?
这是一种情况。我有一个对象第一。首先有一个Second对象数组。第二个有第三个对象的数组。
db.myDb.findOne()
{
"_id" : ObjectId("..."),
"Seconds" : [
{
"Second Name" : "value",
"Thirds" : [
{
"Third Name" : "value"
}
]
}
]
}
我有一个显示First对象列表的网站。您可以选择第一个对象,它将显示一个页面,其中显示包含第二个对象列表的第一个详细信息。如果选择第二个对象,则会发生同样的事情。
当提取第三页时,查询获取单个First对象似乎是正确的,然后是一些如何在代码中向下钻取以获取正确的Third对象的数据。直接获取单个第三个对象会更容易,可能是_id。
也许我仍然陷入SQL领域,但在这种情况下,我的想法是为每个类型创建一个集合并让它们相互引用,因为我需要在树中获取单个对象,并且不要在每个请求上保留对象的引用,就像在非Web应用程序中一样。
这是解决这个问题的正确方法吗,还是我在文件领域没有清楚思考?
答案 0 :(得分:1)
我认为这取决于使用情况。如果您经常需要访问“第二”或“第三”项而不包含“ First ”,那么也许最好不要被嵌入。
我曾经用来帮助我确定是否可以更好地嵌入某些东西的问题是问自己它是否是它的一部分或与之相关。例如,' First '实际上是否包含一个或多个' Seconds '(依此类推),或者它们是否以某种方式分开相关的事物?从表面上看,我会说博客帖子包含评论(除非你迫切需要在不知道帖子的情况下查询评论列表),但是用户 / 作者可能不包含帖子列表,而是以某种方式链接但位于不同的集合中。
使用DBRef可以使用MongoDB实现交叉收集关系。这是一种描述与另一个对象的关系的特殊类型。如果您的项目属于他们自己的集合,则他们可以使用DBRef指向彼此。这些可能会以你想要的方式(即第一个中的一个集合,或者每个 Second 可能有一个指向其父节点)。
示例1 - 每个父级都有一组子引用:
db.firsts.findOne()
{
"_id" : ObjectId("..."),
"Seconds" : [
{ $ref : 'seconds', $id : <idvalue> },
{ $ref : 'seconds', $id : <idvalue> },
{ $ref : 'seconds', $id : <idvalue> }
]
}
db.seconds.findOne()
{
"_id" : ObjectId("..."),
"Second Name" : "value",
"Thirds" : [
{ $ref : 'thirds', $id : <idvalue> },
{ $ref : 'thirds', $id : <idvalue> }
]
}
db.thirds.findOne()
{
"_id" : ObjectId("..."),
"Third Name" : "value"
}
示例2 - 每个孩子都有对其父级的引用
db.firsts.findOne()
{
"_id" : ObjectId("...")
}
db.seconds.findOne()
{
"_id" : ObjectId("..."),
"First" : { $ref : 'firsts', $id : <idvalue> }
"Second Name" : "value",
}
db.thirds.findOne()
{
"_id" : ObjectId("..."),
"Second" : { $ref : 'seconds', $id : <idvalue> }
"Third Name" : "value"
}
大多数MongoDB language drivers has a way of dealing with dbrefs比控制台更简洁(通常使用某种'DBRef'类)。以这种方式工作将意味着您有更多的数据库请求,但如果它对您的应用程序有意义,则可能是一个公平的妥协 - 特别是如果您的示例中的“秒”或“三分之一”列表是常用或交互的关键与系统或其功能。
第二种方法最像您使用传统的关系数据库。 MongoDB的优点在于它允许您在实际上有意义的时候进行关系工作,而不是在它没有时。非常灵活,最终取决于您的数据和应用程序对您有意义。最终,您应该使用哪种方法的问题的答案取决于您的应用程序及其存储的数据 - 这不是我们可以从您的示例中看出来的。