Mongoose 与 MongoDB 中的文档嵌套

阅读时长 7 分钟读完

引言

在开发 Web 应用的过程中,我们常常需要对数据进行嵌套,以表现数据之间的逻辑关系。在 MongoDB 中,文档嵌套是一种常见的数据设计方式。而 Mongoose 是 MongoDB 的一个非常流行的 Node.js ORM 库,它封装了 MongoDB 的操作,提供了更加友好和稳定的数据访问接口。本文将介绍如何在 Mongoose 中使用文档嵌套,以及嵌套文档的一些坑点和实践经验。

文档嵌套的基本概念

文档嵌套是指在 MongoDB 的一个文档中,插入另一个文档作为某个字段的值。例如,一个 User 文档可能包含多个 Address 文档,每个 Address 包含 address_line1 和 address_line2 字段。那么在 MongoDB 中,我们可以这样定义一个 User 文档:

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

可以看到,addresses 字段是一个数组,它嵌套了多个 Address 文档。这种文档嵌套方式,在 MongoDB 中被称为 Embedded Document。

在 Mongoose 中使用文档嵌套

在 Mongoose 中使用文档嵌套,也非常简单。我们只需要在模型定义中,将嵌套的字段设置为 Schema.Types.Embedded。

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

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

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

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

上述代码中,我们定义了 User 模型,该模型中的 addresses 字段,使用了 AddressSchema ,即文档嵌套了 Address。在使用时,我们可以像普通字段一样使用 addresses 字段:

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

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

坑点与实践经验

1. 文档嵌套的级数

在使用文档嵌套时,需要注意文档嵌套的级数。在 MongoDB 中,最多支持嵌套 100 级文档。如果超过了这个限制,MongoDB 将无法存储数据。而在 Mongoose 中,默认为 1 级,即只支持嵌套 1 级文档。如果需要支持更多级别的嵌套,需要手动设置 Schema 中的嵌套层数。

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

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

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

上述代码中,我们定义了一个 User 模型,该模型中的 addresses 字段支持 1 级文档嵌套,而 friends 字段支持多级嵌套。可以看到,我们使用了 Schema.add() 方法,为 UserSchema 动态添加了 friends 字段,以支持多级文档嵌套。

2. subdocument 中的 _id 细节

在使用文档嵌套时,需要注意 subdocument 中的 _id 细节。在 MongoDB 中,默认情况下,每个文档都会有一个唯一的 _id 字段。但 subdocument 中的 _id 字段并不是必需的。如果不需要 _id 字段,则可以在 Schema 中设置 _id:false 选项。

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

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

上述代码中,我们定义了一个 Address 模型,该模型中的文档不需要 _id 字段。

3. populate 的使用

当 subdocument 嵌套过深时,在查询中使用 populate 可能会失效。例如,我们查询一个 User,想要同时获取其所有 Address 的详细信息:

可以看到,上述代码使用了 populate 方法,将 addresses 字段从 ID 转换为了实际的 Address 对象。这种方法在一级嵌套时非常好用,但在多级嵌套时可能会失效。

在多级嵌套时,我们可以手动查询每个级别的文档:

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

上述代码中,我们使用了两个查询,分别查询了 User 和 Address 对象,然后手动将两个对象关联起来。这种方法虽然会增加代码复杂度,但能够有效避免 populate 失效的问题。

小结

本文介绍了 MongoDB 中的 Embedded Document,以及在 Mongoose 中使用文档嵌套的方法和坑点。同时,我们也分享了一些文档嵌套的实践经验和技巧。在开发中,适当的文档嵌套可以让数据逻辑更加清晰和紧凑,代码更加精简和易读。希望本文能够对读者有所启发和帮助,欢迎大家多多交流和分享。

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

纠错
反馈