You need to enable JavaScript to run this app. Mongoose自定义_id如何设置默认值为ObjectId,字符串_id是否有使用隐患
优惠活动
大模型
产品
解决方案
定价
更多

Mongoose自定义_id如何设置默认值为ObjectId,字符串_id是否有使用隐患

问题解答

实现自定义字符串_id和默认ObjectId类型_id共存的方案

你当前代码存在两个核心问题:

  1. 把_id的type强制指定为String,无论默认值传入什么类型,Mongoose都会自动转为字符串存储
  2. 现有default写法存在严重错误:直接调用mongoose.Types.ObjectId()会在Schema加载时生成一个固定的ObjectId,所有未手动指定_id的用户都会共用同一个_id,生产环境会直接报主键冲突错误

正确配置如下,使用Mixed混合类型支持同时存储字符串和ObjectId类型,同时将默认值改为函数形式,确保每次新建文档生成全新的ObjectId:

const userSchema = new mongoose.Schema({
  _id: { 
    type: mongoose.Schema.Types.Mixed,
    // 函数形式默认值,每次新建无自定义_id的文档时生成新的ObjectId
    default: () => new mongoose.Types.ObjectId(),
    required: true
  },
  password: String,
  fName: String,
  lName: String,
  email: { type: String, unique: true, lowercase: true },
  blogs: [blogSchema],
  followers: Array,
  followings: Array,
  darkMode: Boolean,
});

配置完成后,手动传入字符串类型_id时会直接存储字符串,未传入时默认存储原生ObjectId类型。

默认_id使用字符串类型的潜在问题

如果坚持将默认_id设为字符串类型,会存在以下风险:

  • 存储成本升高:原生ObjectId是12字节的二进制存储,转换为24位字符串后存储空间翻倍,数据量较大时会明显提升存储成本
  • 查询性能下降:字符串类型的主键索引、排序性能弱于原生ObjectId,数据量超过十万级时接口响应延迟会有可感知的上升
  • 兼容性问题:MongoDB原生操作、Mongoose内置方法(如populate关联、$lookup聚合查询)默认期望_id为ObjectId类型,字符串_id会出现关联两边类型不匹配导致查询为空的问题,需要额外编写类型转换逻辑,提升代码复杂度
  • 额外错误风险:即使修正默认值为动态生成字符串的写法,也可能在跨服务传参、类型校验时出现不必要的错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.17 16:15:04