MongoDB中的關(guān)系表示不同文檔之間的邏輯關(guān)系。關(guān)系可以通過嵌入的和引用的方法來建模。這種關(guān)系可以是1:1、1:N、N:1或N:N。
讓我們考慮為用戶存儲(chǔ)地址的情況。因此,一個(gè)用戶可以有多個(gè)地址,這就形成了1:N的關(guān)系。
以下是文檔的示例文檔結(jié)構(gòu)user-
{
"_id":ObjectId("52ffc33cd85242f436000001"),
"name": "Tom Hanks",
"contact": "987654321",
"dob": "01-01-1991"
}以下是文檔的示例文檔結(jié)構(gòu)address-
{
"_id":ObjectId("52ffc4a5d85242602e000000"),
"building": "22 A, Indiana Apt",
"pincode": 123456,
"city": "Los Angeles",
"state": "California"
}在嵌入式方法中,我們將地址文檔嵌入到用戶文檔中。
> db.users.insert({
{
"_id":ObjectId("52ffc33cd85242f436000001"),
"contact": "987654321",
"dob": "01-01-1991",
"name": "Tom Benzamin",
"address": [
{
"building": "22 A, Indiana Apt",
"pincode": 123456,
"city": "Los Angeles",
"state": "California"
},
{
"building": "170 A, Acropolis Apt",
"pincode": 456789,
"city": "Chicago",
"state": "Illinois"
}
]
}
})這種方法將所有相關(guān)數(shù)據(jù)保存在一個(gè)文檔中,這使得檢索和維護(hù)更加容易。可以在單個(gè)查詢中檢索整個(gè)文檔,例如-
>db.users.findOne({"name":"Tom Benzamin"},{"address":1})注意在上面的查詢中,db和users分別是數(shù)據(jù)庫和集合。
缺點(diǎn)是,如果嵌入文檔的大小持續(xù)增長過大,可能會(huì)影響讀/寫性能。
這是規(guī)范化關(guān)系設(shè)計(jì)的途徑。在這種方法中,用戶文檔和地址文檔將分開維護(hù),但用戶文檔將包含一個(gè)引用地址文檔 id 字段的字段。
{
"_id":ObjectId("52ffc33cd85242f436000001"),
"contact": "987654321",
"dob": "01-01-1991",
"name": "Tom Benzamin",
"address_ids": [
ObjectId("52ffc4a5d85242602e000000"),
ObjectId("52ffc4a5d85242602e000001")
]
}如上所示,用戶文檔包含數(shù)組字段address_ids,它包含對(duì)應(yīng)地址的對(duì)象ObjectId。使用這些對(duì)象ObjectId,我們可以查詢地址文檔并從那里獲得地址詳細(xì)信息。使用這種方法,我們將需要兩個(gè)查詢:首先address_ids從user文檔中獲取字段,其次從address集合中獲取這些地址。
>var result = db.users.findOne({"name":"Tom Benzamin"},{"address_ids":1})>var addresses = db.address.find({"_id":{"$in":result["address_ids"]}})