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

Mongoose中使用insertMany为何无法生成ObjectId类型的_id?

问题

使用Node.js和MongoDB开发应用时,尝试插入多条带有预定义_id及ObjectId数组的文档,遇到以下问题:

  • 调用insertMany插入时,所有文档的_id字段显示为字符串类型,而非预期的ObjectId类型;
  • 调用create传入数组时,_id能正常生成ObjectId,但会为数组内每个元素执行单独查询,数据量增大时性能问题会很突出。

请问如何通过insertMany创建_id为ObjectId类型的文档?

当前使用的插入代码:

Model.insertMany([
{_id: new mongoose.Types.ObjectId(), ...},
{_id: new mongoose.Types.ObjectId(), ...},
])

Schema配置选项:

{
  ...
  toObject: {flattenObjectIds: true},
  ...
}

解决方案

问题根源在于Schema配置中的toObject: {flattenObjectIds: true}——这个配置会将ObjectId类型字段自动序列化为字符串,导致你看到的_id是字符串格式,但实际上MongoDB数据库中存储的仍然是ObjectId类型。可以通过以下方式调整:

  1. 修改Schema的序列化配置
    直接移除flattenObjectIds: true,或者将其设置为false,这样ObjectId字段就不会被自动转换为字符串:
{
  ...
  toObject: {flattenObjectIds: false},
  // 也可以直接删除这个配置项,因为默认行为就是不扁平化ObjectId
  ...
}
  1. 确认实际存储类型
    你当前用new mongoose.Types.ObjectId()生成的_id本身就是ObjectId类型,插入MongoDB后,数据库内存储的是正确的ObjectId。之前看到的字符串只是序列化后的展示结果,并非实际存储的类型,可以通过MongoDB Compass等工具直接查看数据库验证这一点。

  2. 自定义字段序列化规则(可选)
    如果需要保留其他toObject配置,又不想让_id被转成字符串,可以单独为_id字段设置序列化规则:

const yourSchema = new mongoose.Schema({
  _id: {
    type: mongoose.Schema.Types.ObjectId,
    default: mongoose.Types.ObjectId,
    transform: (value) => value // 保留原ObjectId类型,不转换为字符串
  },
  // 其他字段定义...
}, {
  toObject: {
    // 你的其他序列化配置
  }
});

内容的提问来源于stack exchange,提问作者Codie

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 01:33:22