使用Mongoose遇Customer.findByIdAndUpdate is not a function错误求助
Customer.findByIdAndUpdate is not a function错误 问题背景
使用MongoDB、Mongoose和Express开发客户数据库管理系统,主营二手复印机/打印机转售及维护合约业务,客户与机器为关联文档。删除机器时触发以下错误:
Customer.findByIdAndUpdate is not a function
TypeError: Customer.findByIdAndUpdate is not a function at module.exports.deleteMachine (C:\controllers\machines.js:21:20) at C:\utils\catchAsync.js:3:9 at Layer.handle [as handle_request] (C:\node_modules\express\lib\router\layer.js:95:5) at next (C:\node_modules\express\lib\router\route.js:144:13) at module.exports.getCustomer (C:\middleware.js:15:5) at processTicksAndRejections (node:internal/process/task_queues:96:5)
相关代码如下:
机器控制器
const Customer = require('../models/customer'); const Machine = require('../models/machine'); module.exports.deleteMachine = async (req, res) => { const { id, machineId } = req.params; await Customer.findByIdAndUpdate(id, { $pull: { machines: machineId } }); await Machine.findByIdAndDelete(machineId); req.flash('success', 'Machine has been deleted'); res.redirect(`/customers/${id}`); };
机器路由
router.delete('/:machineId', getCustomer, catchAsync(machines.deleteMachine));
getCustomer中间件
module.exports.getCustomer = async (req, res, next) => { const { id } = req.params; const customer = await Customer.findById(id).populate({ path: 'machines' }); if (!customer) { req.flash('error', 'Sorry, that customer cannot be found!'); return res.redirect('/customers'); } res.locals.foundCustomer = customer; next(); };
app.js路由配置
const customerRoutes = require('./routes/customers'); const machineRoutes = require('./routes/machines'); app.use('/customers', customerRoutes); app.use('/customers/:id/machines', machineRoutes);
客户模型
const customerSchema = new Schema({ customer: String, customerID: String, category: { type: String, enum: ['contracted', 'billable'] }, contacts: [contactSchema], address: String, city: String, state: String, zip: String, county: String, machines: [ { type: Schema.Types.ObjectId, ref: 'Machine' } ], notes: [noteSchema] });
问题原因
错误核心是Customer模型未正确导出为Mongoose模型对象。你提供的客户模型仅定义了Schema,但缺少mongoose.model()的导出语句,导致require('../models/customer')获取的不是具备静态方法的模型实例,自然无法调用findByIdAndUpdate。
解决方案
补全客户模型的导出代码
在客户模型文件末尾添加以下代码:const mongoose = require('mongoose'); // (已有的Schema定义) module.exports = mongoose.model('Customer', customerSchema);确保文件顶部已引入mongoose和Schema:
const mongoose = require('mongoose'); const Schema = mongoose.Schema;验证模型导出与路径正确性
检查控制器中const Customer = require('../models/customer')的路径是否指向正确的模型文件,确认文件确实导出了Mongoose模型而非仅Schema。优化代码(可选)
利用中间件中已查询到的res.locals.foundCustomer进行更新,减少重复查询:// 在deleteMachine控制器中替换原更新语句 await res.locals.foundCustomer.updateOne({ $pull: { machines: machineId } });同时建议使用Mongoose事务保证操作原子性,避免数据不一致:
const session = await mongoose.startSession(); session.startTransaction(); try { await res.locals.foundCustomer.updateOne({ $pull: { machines: machineId } }, { session }); await Machine.findByIdAndDelete(machineId, { session }); await session.commitTransaction(); req.flash('success', 'Machine has been deleted'); res.redirect(`/customers/${id}`); } catch (err) { await session.abortTransaction(); req.flash('error', 'Failed to delete machine'); res.redirect(`/customers/${id}`); } finally { session.endSession(); }
内容的提问来源于stack exchange,提问作者Makaela

