在关系型数据库中,外键是一种非常常见的概念,它可以用于建立表之间的关联关系。但是,在 MongoDB 这种非关系型数据库中,没有外键的概念。那么,在 MongoDB 中如何使用外键呢?
MongoDB 中的文档关系
在 MongoDB 中,文档之间的关系可以通过嵌套文档或者引用文档的方式实现。
嵌套文档
嵌套文档是指一个文档中包含另一个文档。例如,我们可以在一个订单文档中嵌套一个用户文档:
-- -------------------- ---- -------
-
------ -------------------------------------
------- -
------ -------------------------------------
------- -----
------ --
--
----------- -
- ------- ------ -------- --- --
- ------- ------ -------- --- -
-
-在这个例子中,订单文档中嵌套了一个用户文档,可以通过 order.user.name 来访问用户的名字。
引用文档
引用文档是指一个文档中包含了另一个文档的 _id 值。例如,我们可以在一个订单文档中引用一个用户文档:
{
"_id": ObjectId("5f2b2c2f7d2c2c4b7e0f4d0c"),
"user": ObjectId("5f2b2c2f7d2c2c4b7e0f4d0b"),
"products": [
{ "name": "商品1", "price": 100 },
{ "name": "商品2", "price": 200 }
]
}在这个例子中,订单文档中引用了一个用户文档的 _id 值,可以通过 db.users.findOne({ _id: order.user }) 来访问用户文档。
如何在 MongoDB 中实现外键
虽然 MongoDB 没有外键的概念,但是我们可以通过一些方式来实现类似外键的效果。
手动维护引用关系
我们可以手动在程序中维护文档之间的引用关系。例如,在上面的例子中,我们可以在订单文档中添加一个 user_id 字段,用于存储用户文档的 _id 值。然后,在查询订单文档时,可以通过 db.users.findOne({ _id: order.user_id }) 来访问用户文档。
这种方式的优点是简单易懂,缺点是需要手动维护引用关系,容易出错。
使用 $lookup 操作
MongoDB 3.2 版本以后,可以使用 $lookup 操作实现类似外键的效果。$lookup 操作可以在一个文档中查找另一个集合中的文档,并将它们合并成一个新的文档。
例如,我们可以通过以下代码查询订单文档,并将用户文档合并到订单文档中:
-- -------------------- ---- -------
---------------------
-
-------- -
----- --------
----------- ----------
------------- ------
--- ------
-
-
--这个操作会在 orders 集合中查找每个订单文档的 user_id 字段对应的 _id 值,并在 users 集合中查找对应的用户文档。然后,它会将每个订单文档和它对应的用户文档合并成一个新的文档,并将它们放在一个名为 user 的数组中。
这种方式的优点是不需要手动维护引用关系,缺点是需要使用聚合操作,效率可能较低。
示例代码
以下是一个使用 $lookup 操作实现类似外键的示例代码:
-- -------------------- ---- -------
-- -- ----- --
---------------------
- ------ ------------------------------------- ------- ----- ------ -- --
- ------ ------------------------------------- ------- ----- ------ -- -
--
-- -- ------ --
----------------------
- ------ ------------------------------------- ---------- ------------------------------------- ----------- -- ------- ------ -------- --- -- - ------- ------ -------- --- -- --
- ------ ------------------------------------- ---------- ------------------------------------- ----------- -- ------- ------ -------- --- -- - ------- ------ -------- --- -- -
--
-- --------------
---------------------
-
-------- -
----- --------
----------- ----------
------------- ------
--- ------
-
-
--这个示例代码会输出以下结果:
-- -------------------- ---- -------
-
-
------ -------------------------------------
---------- -------------------------------------
----------- -
- ------- ------ -------- --- --
- ------- ------ -------- --- -
--
------- -
- ------ ------------------------------------- ------- ----- ------ -- -
-
--
-
------ -------------------------------------
---------- -------------------------------------
----------- -
- ------- ------ -------- --- --
- ------- ------ -------- --- -
--
------- -
- ------ ------------------------------------- ------- ----- ------ -- -
-
-
-可以看到,每个订单文档都包含了对应的用户文档。
Source: FunTeaLearn,Please indicate the source for reprints https://funteas.com/post/67d9a489a941bf7134155d14