2010-02-25 28 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的美妙之處在於它允許你在關係上工作,但實際上它是有意義的,而不是在沒有關係的時候。非常靈活,最終取決於您的數據和應用程序,以確定哪些對您有意義。最終,您應該使用哪種方法的問題的答案取決於您的應用程序及其存儲的數據 - 而不是我們可以從您的示例中得出的結果。