ObjectId 跨版本兼容性
概述
monSQLize 从 v1.1.1 开始支持跨 BSON 版本的 ObjectId 兼容,可以无缝处理来自其他 MongoDB 库(如 mongoose)的 ObjectId 对象。
问题背景
当您的项目混用多个 MongoDB 库时,可能会遇到 BSON 版本冲突问题:
根本原因:
- mongoose 依赖
bson@4.x或bson@5.x - monSQLize 使用
mongodb@6.x内部依赖bson@6.x - mongodb@6.x 驱动拒绝接受非
bson@6.x的 ObjectId 实例
解决方案
monSQLize 内置了自动跨版本 ObjectId 转换功能,无需手动处理:
✅ 自动转换(推荐)
工作原理
monSQLize 的 convertObjectIdStrings 函数会:
- 检测旧版本 ObjectId:通过
constructor.name === 'ObjectId'识别 - 安全转换:调用
.toString()获取十六进制字符串,再构造为bson@6.x版本 - 递归处理:自动处理嵌套对象和数组中的 ObjectId
- 错误降级:转换失败时返回原对象,不影响其他字段
支持的场景
1. 单个 ObjectId
2. 嵌套对象
3. ObjectId 数组
4. 查询条件
性能优化
- 零拷贝优化:如果对象中没有需要转换的 ObjectId,返回原对象(不克隆)
- 智能检测:只处理字段名匹配
_id,*Id,*Ids等模式的字段 - 深度限制:递归深度默认限制为 10 层,防止栈溢出
兼容性
手动预处理(仅在应用层确有需要时)
v2 当前对外承诺的是自动跨版本 ObjectId 转换。monsqlize/lib/utils/objectid-converter 属于迁移期 legacy helper 子路径,不再建议作为正式依赖入口。
如果业务确实需要在进入 monSQLize 前显式归一化数据,请在应用层自行做预处理,再把结果交给 monSQLize;不要把旧 helper 子路径当作长期公开 API。
调试
启用日志查看转换过程:
注意事项
- 字段引用不转换:MongoDB 聚合管道中的字段引用(如
$userId)不会被转换 - 特殊操作符:
$expr,$function,$where等内部不转换 - 循环引用检测:自动检测并防止循环引用导致的无限递归
- 错误降级:转换失败时返回原值,不会抛出异常
相关链接
更新日志
- v1.1.1 (2026-01-27):新增跨版本 ObjectId 兼容性支持