2017-09-27 102 views
0

假設我們有以下類別:MongoDB的 - 如何正確建模關係

Users 
{ 
    "id": MongoId, 
    "username": "jsloth", 
    "first_name": "John", 
    "last_name": "Sloth", 
    "display_name": "John Sloth" 
} 

Places 
{ 
    "id": MongoId, 
    "name": "Conference Room", 
    "description": "Some longer description of this place" 
} 

Meetings 
{ 
    "id": MongoId, 
    "name": "Very important meeting", 
    "place": <?>, 
    "timestamp": "1506493396", 
    "created_by": <?> 
} 

後來,我們想返回(例如,從REST Web服務)這樣的即將到來的事件列表:

[ 
    { 
     "id": MongoId(Meetings), 
     "name": "Very important meeting", 
     "created_by": { 
     "id": MongoId(Users), 
     "display_name": "John Sloth", 
     }, 
     "place": { 
     "id": MongoId(Places), 
     "name": "Conference Room", 
     } 
    }, 
    ... 
] 

重要的是返回需要顯示在web ui主頁上的基本信息(因此不需要額外的調用來呈現表)。這就是爲什麼,每個條目包含創建它的用戶display_name以及該地點的name。我認爲這是一個很常見的情況。

現在我的問題是:我應該如何將此信息存儲在db(Metting文檔中的問號值)?我看到2個選項:

1)店鋪引用其他集合:

place: MongoId(Places) 

(+)數據始終是一致的

( - )額外調用數據庫有爲了進行構建響應

2)進行非標準化數據:

"place": { 
    "id": MongoId(Places), 
    "name": "Conference room", 
    } 

(+),無需額外的調用(響應可以根據一個文件來構造)

( - )數據必須每次相關的文件被修改

什麼是處理的適當方式進行更新有這種情況?

如果我使用選項1),我應該如何查詢其他文檔?分別詢問每個相關文檔看起來像是過度殺傷。如何獲得最後20次會議,彙總相關文件列表,然後執行如db.users.find({_id: { $in: <id list> }})這樣的查詢?

如果我選擇2),我應該如何保持數據同步?

在此先感謝您的任何建議!

回答

0

由於MongoDB在3.2版中引入了$lookup aggregation,所以您可以保留已有的數據庫模型,並且仍然只執行單個查詢。這與加入RDBMS類似。

$查找

執行左外連接到unsharded集合在同一個數據庫中的「加盟」收集處理文檔進行過濾。 $ lookup階段在輸入文檔的字段與「已加入」集合的文檔中的字段之間進行平等匹配。

因此,不是存儲對其他集合的引用,而是存儲文檔ID。

+0

我不知道部分「unsharded集合」。說實話,它現在對我很有用,因爲我沒有任何分片收藏。但是,如果相關集合被分割了,怎麼辦? – jbacic

+0

據我所知,沒有其他方式分片收集https://stackoverflow.com/questions/34633111/mongodb-to-use-sharding-with-lookup-aggregation-operator。但是通常你必須存儲一些數據並且有一些用戶可以爲分片辯護。 – str