解决Mongoose Schema向MongoDB存储空数组的问题
解决Mongoose数组字段空值不触发required验证的问题
问题背景
我使用Express + Node.js开发API,通过Mongoose将数据存储到MongoDB,设计的MessagesSchema如下:
const MessagesSchema = new mongoose.Schema( { readReceipt: { type: String, required: [true, "Read Receipt Mandatory"], enum: { values: ["sent", "received", "read"], message: `Invalid value {VALUE}`, }, }, messageContent: { type: String }, sentBy: { type: mongoose.Schema.Types.ObjectId, ref: "Users", required: [true, "Sender cannot be Empty"], }, sentTo: { type: [mongoose.Schema.Types.ObjectId], ref: "Users", required: [true, "At Least One senderId required"], }, }, { timestamps: true } );
但实际存入数据库的数据中,sentTo字段为空数组却未触发必填验证:
{ "readReceipt": "sent", "messageContent": "Test Message 4", "sentBy": "6728a8b1b6fd6ebeac8e0fa5", "sentTo": [], "_id": "672b2539d7f2f99e8f9ef738", "createdAt": "2024-11-06T08:13:45.080Z", "updatedAt": "2024-11-06T08:13:45.080Z", "__v": 0 }
使用版本:
- mongoose: "8.8.0"
- express: "4.21.1"
- node: "18.18.0"
核心原因
Mongoose中required: true对数组类型仅验证数组本身存在,空数组属于合法存在的数组,因此不会触发报错。要限制数组不能为空,需额外添加验证规则。
可行解决方案
方案1:使用minLength验证规则
直接在sentTo字段配置中添加minLength,指定数组最小长度为1:
sentTo: { type: [mongoose.Schema.Types.ObjectId], ref: "Users", required: [true, "At Least One senderId required"], minLength: [1, "At Least One recipient required"] }
方案2:自定义验证函数
如果需要更灵活的验证逻辑,可使用自定义验证器:
sentTo: { type: [mongoose.Schema.Types.ObjectId], ref: "Users", required: [true, "At Least One senderId required"], validate: { validator: function(v) { return v.length > 0; }, message: "At Least One recipient required" } }
方案3:结合required与default(可选)
设置default: undefined避免Mongoose自动给数组填充空默认值,配合required强制传入非空数组:
sentTo: { type: [mongoose.Schema.Types.ObjectId], ref: "Users", required: [true, "At Least One senderId required"], default: undefined }
注意:若数据库中已存在空数组的历史数据,修改Schema后需手动清理或在更新时触发验证逻辑。
内容的提问来源于stack exchange,提问作者y.d_edition
相关产品推荐
相关产品推荐

