Mongoose 中有关 Virtuals 和 Populate 的问题解决

阅读时长 7 分钟读完

在 Mongoose 中,Virtuals 和 Populate 是两个非常常用的功能。Virtuals 可以让我们在获取数据时动态生成新的属性,而 Populate 可以让我们在查询时将关联数据一起查询出来。但是,在使用这些功能时也会遇到一些问题。在本文中,我们将介绍如何解决 Virtuals 和 Populate 的常见问题。

Virtuals 的问题解决

问题一:Virtuals 不能被查询

Virtuals 默认情况下是不能被查询的,因为 Virtuals 并不存在于数据库中。但是,我们可以通过设置 virtuals: true 选项来让 Mongoose 返回包含 Virtuals 的查询结果。示例代码如下:

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

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

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

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

问题二:Virtuals 的 get 和 set 函数不能被异步执行

虽然 Virtuals 的 get 和 set 函数看起来是普通的 JavaScript 函数,但它们在使用时必须是同步执行的。例如,下面的代码是错误的:

这是因为 Mongoose 使用的是 Object.defineProperty 来定义 Virtuals,而 Object.defineProperty 不支持异步函数。

解决方法是将异步操作放到 Virtuals 的 set 函数中。例如,我们可以将上面的 Virtuals 修改为以下代码:

Populate 的问题解决

问题一:Populate 的查询结果嵌套层数过多

Populate 能够让我们在查询时一次性地将多个关联数据查询出来,但是这会导致查询结果的嵌套层数过多,使查询结果难以处理。例如,下面的代码展示了通过多次使用 populate 查询嵌套数据的方式,查询 Order 数据关联的 User 和 Product 数据的问题。

解决方法是使用 leanobjectId 选项避免多层嵌套。lean 选项可以让查询结果变成普通的 JavaScript 对象,而不是 Mongoose 的 Model 实例,这样就能够避免数据的嵌套。objectId 选项可以将关联的 ObjectId 转为字符串,使得查询结果中包含的关联数据与主数据可以分开处理。例如,下面的代码展示了使用 leanobjectId 选项处理 Order 数据的查询结果的方式。

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

问题二:Populate 只能查询单个字段

默认情况下,Populate 只能查询单个字段。但是,在某些情况下,我们可能需要查询多个字段。例如,在查询文章时需要查询作者的全部信息,包括姓名、邮箱、头像等。此时,我们需要使用自定义查询函数来实现。

示例代码如下:

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

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

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

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

总结

Virtuals 和 Populate 是 Mongoose 中非常常用的功能。在使用这些功能时,我们可能会遇到一些问题,例如 Virtuals 不能被查询和 Populate 的查询结果嵌套层数过多等。本文介绍了如何解决这些问题,提供了详细的示例代码。希望本文能够对你在使用 Mongoose 时遇到的问题有所帮助。

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

纠错
反馈