monSQLize 从 v1.1.1 开始支持跨 BSON 版本的 ObjectId 兼容,可以无缝处理来自其他 MongoDB 库(如 mongoose)的 ObjectId 对象。
当您的项目混用多个 MongoDB 库时,可能会遇到 BSON 版本冲突问题:
// 其他服务使用 mongoose (bson@4.x 或 bson@5.x)
const dataFromMongoose = await MongooseModel.findOne({ ... }).lean();
// monSQLize 使用 mongodb@6.x (bson@6.x)
await msq.collection('orders').insertOne(dataFromMongoose);
// ❌ 错误:Unsupported BSON version, bson types must be from bson 6.x.x根本原因:
- mongoose 依赖
bson@4.x或bson@5.x - monSQLize 使用
mongodb@6.x内部依赖bson@6.x - mongodb@6.x 驱动拒绝接受非
bson@6.x的 ObjectId 实例
monSQLize 内置了自动跨版本 ObjectId 转换功能,无需手动处理:
const MonSQLize = require('monsqlize');
// 从 mongoose 获取数据(包含 bson@4.x/5.x 的 ObjectId)
const dataFromMongoose = await MongooseModel.findOne({ ... }).lean();
// 直接插入,monSQLize 自动转换 ObjectId
const result = await msq.collection('orders').insertOne(dataFromMongoose);
// ✅ 成功:自动将旧版本 ObjectId 转换为 bson@6.x 版本monSQLize 的 convertObjectIdStrings 函数会:
- 检测旧版本 ObjectId:通过
constructor.name === 'ObjectId'识别 - 安全转换:调用
.toString()获取十六进制字符串,再构造为bson@6.x版本 - 递归处理:自动处理嵌套对象和数组中的 ObjectId
- 错误降级:转换失败时返回原对象,不影响其他字段
// mongoose 的 ObjectId
const legacyUserId = mongoose.Types.ObjectId('507f1f77bcf86cd799439011');
// 自动转换
await msq.collection('users').insertOne({
userId: legacyUserId, // ✅ 自动转换
name: 'Alice'
});const order = {
_id: mongooseObjectId1,
userId: mongooseObjectId2,
items: [
{ productId: mongooseObjectId3, qty: 2 },
{ productId: mongooseObjectId4, qty: 1 }
],
metadata: {
createdBy: mongooseObjectId5,
updatedBy: mongooseObjectId6
}
};
// 所有 ObjectId 自动转换
await msq.collection('orders').insertOne(order);const userIds = [
mongooseObjectId1,
mongooseObjectId2,
mongooseObjectId3
];
await msq.collection('groups').insertOne({
name: 'Group A',
members: userIds // ✅ 数组中的所有 ObjectId 自动转换
});// 查询条件中的 ObjectId 也会自动转换
const result = await msq.collection('orders').find({
userId: mongooseObjectId // ✅ 自动转换
});- 零拷贝优化:如果对象中没有需要转换的 ObjectId,返回原对象(不克隆)
- 智能检测:只处理字段名匹配
_id,*Id,*Ids等模式的字段 - 深度限制:递归深度默认限制为 10 层,防止栈溢出
| BSON 版本 | mongoose 版本 | monSQLize 支持 |
|---|---|---|
| bson@4.x | mongoose@5.x | ✅ 完全支持 |
| bson@5.x | mongoose@6.x | ✅ 完全支持 |
| bson@6.x | mongoose@7.x | ✅ 原生支持 |
如果您需要手动控制转换过程:
const { convertObjectIdStrings } = require('monsqlize/lib/utils/objectid-converter');
// 手动转换
const converted = convertObjectIdStrings(dataFromMongoose);
await msq.collection('orders').insertOne(converted);启用日志查看转换过程:
const msq = new MonSQLize({
type: 'mongodb',
databaseName: 'mydb',
config: { uri: 'mongodb://localhost:27017' },
logger: {
level: 'debug' // 启用调试日志
}
});
// 插入时会输出转换日志
await msq.collection('orders').insertOne(dataFromMongoose);
// [DEBUG] [ObjectId Converter] Cross-version ObjectId converted
// { from: 'ObjectId', to: 'ObjectId', hex: '507f1f77bcf86cd799439011' }- 字段引用不转换:MongoDB 聚合管道中的字段引用(如
$userId)不会被转换 - 特殊操作符:
$expr,$function,$where等内部不转换 - 循环引用检测:自动检测并防止循环引用导致的无限递归
- 错误降级:转换失败时返回原值,不会抛出异常
- v1.1.1 (2026-01-27):新增跨版本 ObjectId 兼容性支持