如何在Mongoose Schema中仅保存指定对象(school/college/work)
解决Mongoose自动创建未使用对象的问题
你遇到的问题根源在于给school、college、work这三个子对象都设置了默认空对象,Mongoose会自动把默认值插入数据库,哪怕你没给这些字段赋值。所以要省略未使用的对象,核心就是去掉这些默认配置,再配合验证或钩子确保数据合规。
步骤1:移除子对象的default配置
把每个子对象里的default: ""都删掉,同时可以给type字段加上enum限制,确保只能是指定的三个值,避免无效输入:
let mySchema = new Schema({ "type": { type: String, required: true, enum: ['school', 'college', 'work'] // 限定type的可选值 }, "school": { 'name':{ type: String }, 'parent':{ type: String }, 'address':{ type: String }, 'email_id':{ type: String }, 'phone_no':{ type: String }, }, "college": { 'name':{ type: String }, 'friend':{ type: String }, 'address':{ type: String }, 'email_id':{ type: String }, 'phone_no':{ type: String }, }, "work": { 'name':{ type: String }, 'colleague':{ type: String }, 'address':{ type: String }, 'email_id':{ type: String }, 'phone_no':{ type: String }, }, });
这样修改后,如果你只给school赋值,college和work字段就不会被存入数据库。
步骤2:添加验证/钩子确保数据合规(可选但推荐)
为了避免同时存入多个子对象的情况,可以加个预保存钩子,自动删除和type不匹配的字段:
mySchema.pre('save', function(next) { const allFields = ['school', 'college', 'work']; // 只保留和type对应的字段,删除其他 allFields.forEach(field => { if (field !== this.type) { delete this[field]; } }); next(); });
或者用验证规则,阻止同时存在多个子对象的情况:
mySchema.path('type').validate(function(value) { const allFields = ['school', 'college', 'work']; // 检查是否有和type不匹配的字段被赋值 const extraFields = allFields.filter(field => field !== value && this[field] != null); return extraFields.length === 0; }, '只能保存与type匹配的对象字段');
关于default参数的说明
你不应该给这三个子对象设置default,因为default的作用是当字段未赋值时自动插入默认值,这正是导致未使用对象被创建的原因。只有当你需要确保某个字段必须存在时,才适合用default。
内容的提问来源于stack exchange,提问作者Kiddo
相关产品推荐
相关产品推荐

