2010-02-25 63 views
1

由于它确实是not possible to return a single embedded document(还没有),什么是一个好的数据库设计替代方案?MongoDB Alternative Design

这是一种情况。我有一个对象第一。首先有一个第二个对象的数组。其次是第三个对象的数组。

db.myDb.findOne() 
{ 
    "_id" : ObjectId("..."), 
    "Seconds" : [ 
     { 
      "Second Name" : "value", 
      "Thirds" : [ 
       { 
        "Third Name" : "value" 
       } 
      ] 
     } 
    ] 
} 

我有一个网站显示了第一个对象的列表。您可以选择第一个对象,它会带您进入显示第一个细节的页面,其中包含第二个对象的列表。如果您选择第二个对象,则会发生同样的事情。

当拉起第三页时,查询得到单个第一个对象看起来不太合适,然后在代码中深入了解如何获取正确的第三个对象的数据。直接获取单个第三个对象(可能通过_id)会容易得多。

也许我仍然陷在了SQL的土地,但在这种情况下,我的想法是为每个类型创建一个集合,并让它们互相引用,因为我需要将单个对象放在树中,并且不会在每个请求中保留对某个对象的引用,就像您可以在非Web应用程序中一样。

请问这是解决这个问题的正确方法,还是我没有在文档土地上清楚地思考?

回答

1

我认为这将取决于用法。如果您经常需要访问'第二'或'第三'项目没有包含'第一',那么也许他们最好不要嵌入。

我曾经用来帮助我确定是否可以嵌入更好的问题的一个问题是问自己,它是它的一部分还是与它有关。例如,'第一个'实际上是否包含一个或多个''(等等),还是它们将事件分开?在它面前,我想说一个博客包含评论(除非你有一个迫切需要查询的评论列表而不职位的知识),但用户/作者大概会不包含帖子列表,而是以某种方式链接,但驻留在不同的集合中。

MongoDB使用DBRef可以实现跨集合关系。这是描述与另一个对象的关系的特殊类型。如果你的物品属于他们自己的藏品,他们可以有一个DBRef指向彼此。这些可以以你想要的方式进行(即,它们在第一个中的集合,或者每个第二个可以有一个指向它的父母第一个)。

实施例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'类)。以这种方式工作意味着你有更多的数据库请求,但是如果它对你的应用程序有意义,那么这可能是一个公平的妥协 - 尤其是如果你的例子中的'Seconds'或'Thirds'列表通常是需要的或者是交互的关键与系统或其功能。

第二种方法最像你将使用传统的关系数据库。 MongoDB的美妙之处在于它允许你在关系上工作,但实际上它是有意义的,而不是在没有关系的时候。非常灵活,最终取决于您的数据和应用程序,以确定哪些对您有意义。最终,您应该使用哪种方法的问题的答案取决于您的应用程序及其存储的数据 - 而不是我们可以从您的示例中得出的结果。