@nestjs/mongoose中serializeInto is not a function报错及查询问题
解决@nestjs/mongoose聚合查询中ObjectId匹配的序列化错误问题
问题场景
使用@nestjs/mongoose执行MongoDB聚合查询时,遇到两种异常情况:
- 传入普通字符串类型的
organizationId,无查询结果; - 传入从bson/mongodb/mongoose包导入的ObjectId实例时,抛出序列化错误:
{ "type": "TypeError", "message": "value.serializeInto is not a function", "stack": "TypeError: value.serializeInto is not a function\n at serializeObjectId (/packages/database/node_modules/mongodb/node_modules/bson/src/parser/serializer.ts:240:18)\n at serializeInto (/packages/database/node_modules/mongodb/node_modules/bson/src/parser/serializer.ts:892:17)\n at serializeObject (/packages/database/node_modules/mongodb/node_modules/bson/src/parser/serializer.ts:295:20)\n at serializeInto (/packages/database/node_modules/mongodb/node_modules/bson/src/parser/serializer.ts:875:17)\n at serializeObject (/packages/database/node_modules/mongodb/node_modules/bson/src/parser/serializer.ts:295:20)\n at serializeInto (/packages/database/node_modules/mongodb/node_modules/bson/src/parser/serializer.ts:655:17)\n at serializeObject (/packages/database/node_modules/mongodb/node_modules/bson/src/parser/serializer.ts:295:20)\n at serializeInto (/database/node_modules/mongodb/node_modules/bson/src/parser/serializer.ts:875:17)\n at Object.serialize (/packages/database/node_modules/mongodb/node_modules/bson/src/bson.ts:108:30)\n at OpMsgRequest.serializeBson (/packages/database/node_modules/mongodb/src/cmap/commands.ts:572:17)" }
使用find方法时也会出现相同错误。
原因分析
这个错误的核心是不同依赖包版本的ObjectId实例不兼容:
- 你导入的ObjectId可能来自某个版本的bson/mongodb包,但@nestjs/mongoose依赖的mongodb驱动使用的是另一个版本的bson包;
- 新版本的bson包为ObjectId实例添加了
serializeInto方法用于BSON序列化,而你使用的旧版本ObjectId实例没有这个方法,导致驱动序列化时出错; - 直接传字符串无结果,是因为数据库中
organizationId字段存储的是ObjectId类型,字符串无法和ObjectId直接匹配。
解决方案
1. 使用mongoose内置的Types.ObjectId转换
直接使用mongoose提供的ObjectId工具,确保和驱动依赖的bson版本兼容:
import { Types } from 'mongoose'; // 聚合查询示例 const pipeline = [ { $match: { organizationId: new Types.ObjectId(organizationId), }, }, ]; // 或者简写(Types.ObjectId支持直接调用转换) const pipeline = [ { $match: { organizationId: Types.ObjectId(organizationId), }, }, ];
2. 统一依赖版本
检查package.json中mongoose、mongodb、bson的版本,确保mongoose和mongodb的版本匹配(mongoose官网有明确的版本兼容说明)。删除node_modules和package-lock.json后重新安装,避免多个版本的bson包共存。
3. 聚合查询中用$toObjectId转换字符串
如果不想手动实例化ObjectId,可以在聚合管道中使用MongoDB的$toObjectId操作符将字符串转换为ObjectId后匹配:
const pipeline = [ { $match: { $expr: { $eq: ['$organizationId', { $toObjectId: organizationId }], }, }, }, ];
关于serializeInto的疑问
serializeInto是mongodb驱动依赖的bson包中,为ObjectId实例定义的内部序列化方法,用于将ObjectId转换为BSON格式的数据。当你使用的ObjectId实例来自不兼容的bson版本时,就会缺少这个方法,导致序列化失败。
内容的提问来源于stack exchange,提问作者Yogev Lahyani
相关产品推荐
相关产品推荐

