Mongoose验证器:使用$push后如何验证数组长度?
Mongoose数组$push时长度验证失效的解决方法
你遇到的问题是Mongoose在使用$push更新数组时,字段级别的数组验证器只会拿到新添加的元素而非整个数组,导致长度校验失效。这是因为Mongoose默认对更新操作的数组字段,仅验证被修改的元素而非整个数组。
解决步骤:
更新操作必须启用验证器
执行$push更新时,一定要加上runValidators: true选项,否则Mongoose会跳过字段验证:await YourModel.findByIdAndUpdate( docId, { $push: { importantDates: newDateItem } }, { runValidators: true, new: true } );修改数组验证器逻辑,获取完整数组长度
调整字段级验证器,通过this上下文获取文档当前的数组长度,结合新添加元素的数量进行判断:importantDates: { type: [ { title: { type: String, validate: [ mongooseValidator({ validator: (title) => 1 <= title.length && title.length <= 15, message: 'Invalid important date title. Title must be between 1-15 characters', }), ], }, importantDate: { type: String, validate: [ mongooseValidator({ validator: (importantDate) => date.isValid(importantDate, 'MM/DD/YYYY'), message: 'Invalid important date. Must be in format of mm/dd/yyyy', }), ], }, }, ], validate: [ mongooseValidator({ validator: function(datesList) { // 获取当前文档中数组的已有长度 const currentLength = (this.importantDates || []).length; // 判断新添加元素数量:单个元素加1,批量添加取数组长度 const newItemsCount = Array.isArray(datesList) ? datesList.length : 1; return currentLength + newItemsCount <= 3; }, message: 'Important dates have already reached a maximum of 3. Please remove some to add more.', }), ], default: [], }
替代方案:文档级别验证器
如果觉得字段级验证器的上下文处理麻烦,也可以改用文档级验证器,直接校验整个数组的最终长度:
const yourSchema = new mongoose.Schema({ // 其他字段... importantDates: { type: [ { title: { /* 原有验证逻辑 */ }, importantDate: { /* 原有验证逻辑 */ }, }, ], default: [], } }); // 添加文档级验证器 yourSchema.path('importantDates').validate(function(value) { return value.length <= 3; }, 'Important dates have already reached a maximum of 3. Please remove some to add more.');
这种方式下,只要更新时启用runValidators: true,Mongoose会自动传入完整的数组进行校验。
内容的提问来源于stack exchange,提问作者Brandalf
相关产品推荐
相关产品推荐

