You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 04:40:57