MongoDB中的关系表示各个文档在逻辑上的相互关联。关系可以通过嵌入式和引用方法建模。 这种关系可以是1:1
,1:N
,N:1
或N:N
。
假设有一种情况:要存储用户的地址。一个用户可以拥有多个地址,这就是1:N
关系。
以下是用户(user
)文档示例的文档结构 -
{
"_id":10999110,
"name": "Maxsu",
"contact": "13888990021",
"dob": "1992-10-11"
}
以下是地址(address
)文档的示例文档结构 -
{
"_id":12200,
"building": "Hainan Building NO.2100",
"pincode": 571100,
"city": "Haikou",
"province": "Hainan"
}
嵌入式关系建模
在嵌入式方法中,我们将地址(address
)文档嵌入到用户(user
)文档中。
{
"_id": 21000100,
"contact": "13800138000",
"dob": "1991-11-11",
"name": "Maxsu",
"address": [
{
"building": "Hainan Building NO.2100",
"pincode": 571100,
"city": "Haikou",
"province": "Hainan"
},
{
"building": "Sanya Building NO.2100",
"pincode": 572200,
"city": "Sanya",
"province": "Hainan"
},
]
}
该方法将所有相关数据保存在单个文档中,这使得检索和维护更容易。可以使用单个查询来在整个文档检索,例如 -
> db.users.findOne({"name":"Maxsu"},{"address":1, "name":1})
请注意,在上述查询中,db
和users
分别是数据库和集合。缺点是如果嵌入式文档的大小如果不断增长,可能会影响读/写性能。
建模参考关系
这是设计规范化关系的方法。 在这种方法中,用户和地址文件将分别维护,但用户文档将包含一个将引用地址文档的id
字段的字段。
{
"_id":ObjectId("52ffc33321332111sdfaf"),
"contact": "13800138000",
"dob": "1991-11-11",
"name": "Maxsu",
"address_ids": [
ObjectId("123123"),
ObjectId("123412")
]
}
如上所示,用户文档包含对应地址的ObjectId
的数组字段address_ids
。 使用这些ObjectIds,我们可以从那里查询地址文件并获取地址详细信息。 使用这种方法,需要两个查询:首先从用户文档获取address_ids
字段,然后从地址集中获取这些地址。
>var result = db.users.findOne({"name":"Maxsu"},{"address_ids":1})
>var addresses = db.address.find({"_id":{"$in":result["address_ids"]}})