Node.js操作MongoDB时插入指定_id变为空对象导致插入失败
问题解决:指定ObjectId插入MongoDB后变为空对象的问题
问题背景
在Node.js中使用new ObjectId('24位长度字符串')手动指定文档的_id,调用collection.insertMany插入后,MongoDB里的_id变成了空对象{},导致后续插入因为_id重复(空对象始终相等)而失败。
相关日志与结果
- 插入前
insertMany的入参日志:
[ { _id: { [Symbol(id)]: <Buffer 66 c2 a5 85 44 85 81 17 a7 10 9e 25> }, entity_unique_id: '123' }, { _id: { [Symbol(id)]: <Buffer 66 c2 a5 85 44 85 81 17 a7 10 9e 20> }, entity_unique_id: '456' } ]
- 插入后MongoDB中的实际存储结果(仅插入1条,因
_id重复):
{ "_id" : { }, "entity_unique_id" : "123" }
环境:mongodb驱动4.11.0,MongoDB 3.6.23(Docker Compose部署)
原因
mongodb驱动4.x版本的ObjectId用Symbol封装了内部的Buffer数据,而MongoDB 3.6不支持这种序列化格式,导致_id字段在写入时丢失了实际内容,变成空对象。
解决办法
1. 降级mongodb驱动到兼容版本(推荐)
MongoDB 3.6对应的稳定兼容驱动是3.x系列,比如安装3.7.4版本:
npm uninstall mongodb npm install mongodb@3.7.4
降级后,ObjectId会以MongoDB 3.6能识别的原生格式序列化,插入后的_id会正常存储为ObjectId类型。
2. 手动转换ObjectId格式(不推荐)
如果不想降级驱动,可以在插入前把_id转成字符串(会导致_id存储为字符串类型,而非原生ObjectId,可能影响查询性能和类型匹配):
const { ObjectId } = require('mongodb'); // 转换为字符串后插入 const doc = { _id: new ObjectId('66c2a58544858117a7109e25').toString(), entity_unique_id: '123' };
验证
- 按方法1降级驱动后重新运行插入代码
- 查询集合,确认
_id显示为正常的ObjectId值(如ObjectId("66c2a58544858117a7109e25")) - 插入多条不同
_id的文档,确认不会因重复_id报错
内容的提问来源于stack exchange,提问作者Arc
相关产品推荐
相关产品推荐

