问题描述
在使用 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