在Mongoose Schema中设置default后,required字段是否冗余?
关于Mongoose中default与required共存的作用分析
先明确两个配置的核心逻辑:
default:创建文档时没主动传该字段,自动填充默认值;但如果显式传了undefined,这个配置不会生效。required:强制要求字段必须存在(不管值是你传的还是默认填充的),触发校验时如果字段不存在/为undefined就报错。
所以设置了default之后,required并非完全冗余,在两种特定场景下仍有作用:
1. 防止显式传入undefined
如果有人创建文档时,主动给mode传了undefined,此时default不会触发填充,要是没开required校验,这个字段就会被存成undefined,违反你原本的字段设计(希望它始终是0-3的数字)。而加了required的话,这种操作会直接触发校验错误,阻止无效数据入库。
举个例子:
// 没有required的话,这行代码会成功,mode存为undefined await Project.create({ mode: undefined }); // 有required的话,这行代码会抛出校验错误 await Project.create({ mode: undefined });
2. 阻止更新操作中删除字段
默认情况下Mongoose更新操作不会触发required校验,但如果你开启了runValidators: true选项,当你试图通过$unset删掉mode字段,或者把它设为undefined时,required会立刻报错,避免文档丢失这个必填字段。而default在更新操作中不会自动补全字段,这时候required就是守护字段存在性的关键。
比如:
// 没有required的话,这行代码会成功,文档里的mode字段被删掉 await Project.findOneAndUpdate({}, { $unset: { mode: 1 } }, { runValidators: true }); // 有required的话,这行代码会抛出校验错误 await Project.findOneAndUpdate({}, { $unset: { mode: 1 } }, { runValidators: true });
总结
如果你的业务需要严格保证mode字段永远不能不存在(不管是创建时被刻意传undefined,还是更新时被删除),那required就不是冗余配置,能起到额外的校验防护作用;如果只需要在创建时没传值的情况下用默认值,完全不在意极端情况,那required可以去掉。
内容的提问来源于stack exchange,提问作者Pedro Toriality
相关产品推荐
相关产品推荐

