如何在 MongoDB 中使用外键?

阅读时长 6 分钟读完

在关系型数据库中,外键是一种非常常见的概念,它可以用于建立表之间的关联关系。但是,在 MongoDB 这种非关系型数据库中,没有外键的概念。那么,在 MongoDB 中如何使用外键呢?

MongoDB 中的文档关系

在 MongoDB 中,文档之间的关系可以通过嵌套文档或者引用文档的方式实现。

嵌套文档

嵌套文档是指一个文档中包含另一个文档。例如,我们可以在一个订单文档中嵌套一个用户文档:

-- -------------------- ---- -------
-
  ------ -------------------------------------
  ------- -
    ------ -------------------------------------
    ------- -----
    ------ --
  --
  ----------- -
    - ------- ------ -------- --- --
    - ------- ------ -------- --- -
  -
-
展开代码

在这个例子中,订单文档中嵌套了一个用户文档,可以通过 order.user.name 来访问用户的名字。

引用文档

引用文档是指一个文档中包含了另一个文档的 _id 值。例如,我们可以在一个订单文档中引用一个用户文档:

在这个例子中,订单文档中引用了一个用户文档的 _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 操作实现类似外键的示例代码:

-- -------------------- ---- -------
-- -- ----- --
---------------------
  - ------ ------------------------------------- ------- ----- ------ -- --
  - ------ ------------------------------------- ------- ----- ------ -- -
--

-- -- ------ --
----------------------
  - ------ ------------------------------------- ---------- ------------------------------------- ----------- -- ------- ------ -------- --- -- - ------- ------ -------- --- -- --
  - ------ ------------------------------------- ---------- ------------------------------------- ----------- -- ------- ------ -------- --- -- - ------- ------ -------- --- -- -
--

-- --------------
---------------------
  -
    -------- -
      ----- --------
      ----------- ----------
      ------------- ------
      --- ------
    -
  -
--
展开代码

这个示例代码会输出以下结果:

-- -------------------- ---- -------
-
  -
    ------ -------------------------------------
    ---------- -------------------------------------
    ----------- -
      - ------- ------ -------- --- --
      - ------- ------ -------- --- -
    --
    ------- -
      - ------ ------------------------------------- ------- ----- ------ -- -
    -
  --
  -
    ------ -------------------------------------
    ---------- -------------------------------------
    ----------- -
      - ------- ------ -------- --- --
      - ------- ------ -------- --- -
    --
    ------- -
      - ------ ------------------------------------- ------- ----- ------ -- -
    -
  -
-
展开代码

可以看到,每个订单文档都包含了对应的用户文档。

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67d9a489a941bf7134155d14

纠错
反馈

纠错反馈