Mongoose更新Restaurant文档时lastUpdated字段验证失败求助
Node.js/Express + Mongoose 更新Restaurant文档时lastUpdated必填验证错误问题
错误信息
error Error: Restaurant validation failed: lastUpdated: Path `lastUpdated` is required. at ValidationError.inspect (/opt/render/project/src/node_modules/mongoose/lib/error/validation.js:50:26) at formatValue (node:internal/util/inspect:806:19) at inspect (node:internal/util/inspect:365:10) at formatWithOptionsInternal (node:internal/util/inspect:2304:40) at formatWithOptions (node:internal/util/inspect:2166:10) at console.value (node:internal/console/constructor:338:14) at console.log (node:internal/console/constructor:383:61) at /opt/render/project/src/dist/controllers/MyRestaurantController.js:81:17 at Generator.throw (<anonymous>) at rejected (/opt/render/project/src/dist/controllers/MyRestaurantController.js:6:65) { errors: { lastUpdated: ValidatorError: Path `lastUpdated` is required. at validate (/opt/render/project/src/node_modules/mongoose/lib/schemaType.js:1385:13) at SchemaType.doValidate (/opt/render/project/src/node_modules/mongoose/lib/schemaType.js:1369:7) at /opt/render/project/src/node_modules/mongoose/lib/document.js:3071:18 at process.processTicksAndRejections (node:internal/process/task_queues:85:11) { properties: [Object], kind: 'required', path: 'lastUpdated', value: undefined, reason: undefined, [Symbol(mongoose#validatorError)]: true } }, _message: 'Restaurant validation failed' }
相关代码
Mongoose Schema
const restaurantSchema = new mongoose.Schema({ user: { type: mongoose.Schema.Types.ObjectId, ref: "User" }, restaurantName: { type: String, required: true }, city: { type: String, required: true }, country: { type: String, required: true }, deliveryPrice: { type: Number, required: true }, estimatedDeliveryTime: { type: Number, required: true }, cuisines: [{ type: String, required: true }], menuItems: [menuItemSchema], imageUrl: { type: String, required: true }, lastUpdated: { type: Date, default: Date.now }, }); const Restaurant = mongoose.model("Restaurant", restaurantSchema);
Controller 代码
const updateMyRestaurant = async (req: Request, res: Response) => { try { // Log incoming request data console.log("Request body before update:", req.body); const restaurant = await Restaurant.findOne({ user: req.userId }); if (!restaurant) { return res.status(404).json({ message: "Restaurant not found" }); } // Update fields restaurant.restaurantName = req.body.restaurantName; restaurant.city = req.body.city; restaurant.country = req.body.country; restaurant.deliveryPrice = req.body.deliveryPrice; restaurant.estimatedDeliveryTime = req.body.estimatedDeliveryTime; restaurant.cuisines = req.body.cuisines; restaurant.menuItems = req.body.menuItems; restaurant.lastUpdated = new Date(); if (req.file) { const imageUrl = await uploadImage(req.file as Express.Multer.File); restaurant.imageUrl = imageUrl; } await restaurant.save(); res.status(200).send(restaurant); } catch (error) { console.log("Error during restaurant update:", error); res.status(500).json({ message: "Something went wrong" }); } };
已尝试的排查步骤
- 保存文档前显式为
lastUpdated赋值new Date() - 调用
save()前打印lastUpdated值,确认已被设置 - 反复检查Schema,确认
lastUpdated有默认值且未标记为必填
问题分析与解决建议
可能的原因
- 编译后代码未更新:使用TypeScript开发时,修改Schema后未重新编译,导致运行的
dist目录仍使用旧Schema(旧Schema可能给lastUpdated设置了required: true)。 - 数据库文档缺失字段:目标Restaurant文档在数据库中本身没有
lastUpdated字段,Mongoose默认值仅在新建文档时自动填充,更新现有文档时不会主动补全缺失字段,若存在隐式必填验证就会触发错误。 - 中间件干扰:存在未注意到的
pre('save')中间件,在保存前将lastUpdated重置为undefined。 - 字段赋值被覆盖:
lastUpdated赋值后,被后续逻辑意外覆盖或清除,导致验证时字段值为undefined。
解决建议
- 重新编译并重启服务:执行
tsc编译命令更新dist目录代码,再重启服务,确保最新Schema生效。 - 检查并补全数据库字段:直接查看MongoDB中目标文档,若
lastUpdated缺失,手动添加该字段,或在更新逻辑中先判断字段是否存在再赋值。 - 替换更新方式:改用
findOneAndUpdate替代文档实例的save()方法,直接在更新对象中指定lastUpdated并启用验证:
const updatedRestaurant = await Restaurant.findOneAndUpdate( { user: req.userId }, { ...req.body, lastUpdated: new Date(), ...(req.file ? { imageUrl: await uploadImage(req.file as Express.Multer.File) } : {}) }, { new: true, runValidators: true } );
- 排查中间件逻辑:检查Restaurant模型的
pre('save')钩子,确认是否存在修改lastUpdated的代码。 - 临时关闭验证排查:在
save()时添加{ validateBeforeSave: false },若能成功保存,说明问题出在验证环节,再针对性排查Schema或字段赋值问题。
内容的提问来源于stack exchange,提问作者Franc
相关产品推荐
相关产品推荐

