Mongoose 解析 MongoDB 字符串类型数据的问题和解决方案

问题描述

在使用 Mongoose 操作 MongoDB 数据库时,有时会遇到一个问题:当查询或更新字符串类型的数据时,Mongoose 会将其转换成了 JavaScript 中的对象类型,导致查询或更新失败。

例如,假设有一个名为 users 的集合,其中有一个文档如下:

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

如果我们想要查询名字为 "Alice" 的用户,可以这样写代码:

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

但是,当我们使用 Mongoose 的 populate 方法来填充关联集合数据时,就会遇到问题。

例如,假设有一个名为 posts 的集合,其中有一个文档如下:

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

如果我们想要查询所有文章,并填充对应的作者信息,可以这样写代码:

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

但是,当我们运行这段代码时,会发现查询出来的文章中的 author 字段并不是我们期望的用户对象,而是一个 JavaScript 对象,其属性名为用户对象的每个字段,属性值为对应的值。例如:

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

这是因为,在填充关联集合数据时,Mongoose 会自动将字符串类型的 ObjectId 转换成 JavaScript 对象类型,导致填充失败。

解决方案

为了解决这个问题,我们需要手动将字符串类型的 ObjectId 转换成 MongoDB 的 ObjectId 类型。Mongoose 提供了一个 Types.ObjectId 方法,可以用来将字符串类型的 ObjectId 转换成 MongoDB 的 ObjectId 类型。

例如,我们可以将上面的填充代码修改为:

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

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

在填充关联集合数据时,我们可以在 populate 方法的参数中,使用 transform 选项来手动将字符串类型的 ObjectId 转换成 MongoDB 的 ObjectId 类型。例如,上面的代码中,我们使用了以下代码:

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

这个函数会在填充关联集合数据之前被调用,将 author 字段从字符串类型的 ObjectId 转换成 MongoDB 的 ObjectId 类型。这样,我们就可以成功填充关联集合数据了。

总结

在使用 Mongoose 操作 MongoDB 数据库时,如果遇到字符串类型的 ObjectId 数据转换失败的问题,可以手动使用 Types.ObjectId 方法将其转换成 MongoDB 的 ObjectId 类型,从而解决问题。

在填充关联集合数据时,建议使用 transform 选项来手动转换数据类型,以避免数据转换失败的问题。同时,建议使用 lean 选项来提高查询效率。

示例代码:https://github.com/mongoose/mongoose/issues/6880

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/660e2373d10417a222e97a1b