求助:Mongoose返回对象中ObjectId类型_id无法转为字符串
解决Mongoose文档无法修改_id为字符串的问题
问题重现
通过Mongoose查询得到的文档对象,尝试直接修改_id为字符串时无效果,但其他字段可正常修改:
// 查询得到的Mongoose Document实例 const list = { name: 'Hritik', creator: 'qQzMHzU9SPYhdYq2vswQmfeHd4j2', default: false, _id: new ObjectId('665b1dd655a3a1f154dbb74e'), __v: 0 }; console.log("Before Change", list); list._id = list._id.toString(); // 此修改无效果 list.name = "XYZ"; // 此修改生效 console.log("After Change", list);
输出中_id仍为ObjectId实例,未转为字符串。
原因分析
Mongoose查询返回的是Document实例,而非普通JavaScript对象。这类实例的_id属性被Mongoose通过getter/setter机制封装,直接赋值修改会被拦截,无法覆盖原始的ObjectId值。
解决方案
方案1:转为普通JS对象后修改
使用toObject()或toJSON()方法将Document实例转为普通对象,即可自由修改_id:
console.log("Before Change", list); // 转为普通对象 const plainList = list.toObject(); plainList._id = plainList._id.toString(); plainList.name = "XYZ"; console.log("After Change", plainList);
方案2:查询时直接获取普通对象
如果不需要Mongoose Document的内置方法(如save()),查询时添加lean()选项,直接返回普通JS对象:
// 查询示例 const list = await YourModel.findOne({ /* 查询条件 */ }).lean(); console.log("Before Change", list); list._id = list._id.toString(); // 直接修改生效 list.name = "XYZ"; console.log("After Change", list);
方案3:解构创建新对象
通过解构赋值提取字段,同时重新赋值_id为字符串:
console.log("Before Change", list); const updatedList = { ...list.toObject(), _id: list._id.toString(), name: "XYZ" }; console.log("After Change", updatedList);
内容的提问来源于stack exchange,提问作者Task
相关产品推荐
相关产品推荐

