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
相关产品推荐
相关产品推荐

