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

MongoDB插入嵌套文档自动生成Object ID的原因及解决方法

Mongoose嵌套文档自动生成_id的原因及解决方法

在使用Mongoose向MongoDB插入嵌套文档时,发现嵌套文档部分自动被添加了Object ID,插入时并未传入该字段,但仍自动生成。

原Schema定义

const ticketDetail = mongoose.Schema({
    ticketCount: { type : Number },
    amount: { type : Number },
    pxCount: { type : Number },
    luggageCount: { type : Number },
    cgst: { type : Number },
});
const PaymentModeWiseTDSchema = mongoose.Schema({
        busNumber: { type : String },
        cityId: { type : String },
        cash: ticketDetail,
        prepaid: ticketDetail,
        wallet: ticketDetail,
        pass: ticketDetail,
        mobile_pass: ticketDetail,
        card: ticketDetail,
    },
    {
        collection: 'PaymentModeWiseTD',
        timestamps: true,
    }
);

插入后的文档示例

{
  "_id": "62cc2c69e37ebc0015c0ed43",
  "busNumber": "MP09FA9024",
  "cityId": "46594857",
  "updatedAt": "2022-08-26T12:41:14.806Z",
  "cash": {
    "_id": "6308bf6abb6710802f39571d",
    "amount": 5,
    "pxCount": 4,
    "ticketCount": 3,
    "originalAmount": 5
  },
  "mobile_pass": {
    "_id": "6308bf6abb6710802f39571b",
    "amount": 2,
    "pxCount": 1,
    "ticketCount": 1,
    "originalAmount": 2
  },
  "pass": {
    "_id": "6308bf6abb6710802f39571a",
    "amount": 234567,
    "pxCount": 1,
    "ticketCount": 1,
    "originalAmount": 20
  },
  "prepaid": {
    "_id": "6308bf6abb6710802f39571c",
    "amount": 8,
    "pxCount": 1,
    "ticketCount": 1,
    "originalAmount": 2,
    "discountAmount": 2
  }
}

原因

你定义的ticketDetail是独立的Mongoose Schema,当将其作为嵌套字段使用时,Mongoose默认会为每个嵌套的子文档自动生成_id,这是Mongoose子文档的默认行为。

解决方法

有两种方式可以阻止自动生成_id:

方法一:在子Schema中全局禁用

修改ticketDetail Schema,添加_id: false选项,这样所有使用该Schema的嵌套字段都不会自动生成_id:

const ticketDetail = mongoose.Schema({
    ticketCount: { type : Number },
    amount: { type : Number },
    pxCount: { type : Number },
    luggageCount: { type : Number },
    cgst: { type : Number },
}, { _id: false }); // 添加该选项禁用_id生成

方法二:在父Schema的字段中单独禁用

如果不想修改子Schema的全局设置,可以在父Schema中引用子Schema时,显式指定_id: false:

const PaymentModeWiseTDSchema = mongoose.Schema({
        busNumber: { type : String },
        cityId: { type : String },
        cash: { type: ticketDetail, _id: false },
        prepaid: { type: ticketDetail, _id: false },
        wallet: { type: ticketDetail, _id: false },
        pass: { type: ticketDetail, _id: false },
        mobile_pass: { type: ticketDetail, _id: false },
        card: { type: ticketDetail, _id: false },
    },
    {
        collection: 'PaymentModeWiseTD',
        timestamps: true,
    }
);

两种方法的区别

  • 方法一:对所有使用ticketDetail的场景生效,一次性禁用所有子文档的_id生成。
  • 方法二:仅对当前父Schema中的对应字段生效,其他地方使用ticketDetail时仍会自动生成_id。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 03:45:39