Mongoose导入模型为undefined 调用findOne方法报错
问题现象
从合并了数据库连接逻辑的模型定义文件导入Mongoose模型,调用模型方法时触发报错:Cannot read properties of undefined (reading 'findOne')。
- 已尝试查阅GitHub Issues、StackOverflow大量相关帖子,未找到有效解决方案
- 已尝试添加
autoCreate配置、显式执行await model.init()初始化模型,问题仍存在 - 直接在模型定义文件内部操作模型时,功能可正常运行
相关代码
模型导入&调用代码
const { model } = require("../database"); model.findOne(. . .).then(. . .
初始数据库连接与模型定义代码
mongoose.connect(mongoUri, { dbName: "x" }).then(async () => { const db = mongoose.connection; db.on('error', err => console.error); const schema = new mongoose.Schema({ . . . }); const model = mongoose.model('userprofiles', schema ); module.exports = { mongoose, db, model }; });
尝试修复后的无效代码
mongoose.connect(mongoUri, { dbName: "x", autoCreate: true }).then(async () => { . . . const model = mongoose.model('userprofiles', schema ); await model.init(); module.exports = { mongoose, db, model }; });
问题原因
Node.js CommonJS规范的require是同步执行的,你将module.exports写在了mongoose.connect()的异步.then()回调中。外部文件require该模块时,异步回调还未执行,模块默认导出值为空对象,解构得到的model就是undefined,调用方法自然报错。
直接在模型定义文件内操作模型能正常运行,是因为这部分代码写在.then()回调内部,会等连接成功、模型注册完成后才执行,不存在时序问题。
修复方案
- 不要把模块导出逻辑写在异步回调内。Mongoose自带操作缓存机制,不需要等数据库连接完成再注册、导出模型,未连接阶段调用的模型方法会被缓存,等连接就绪后自动执行。
修复后的参考代码:// 同步注册模型 const schema = new mongoose.Schema({ // ... 字段定义 }); const model = mongoose.model('userprofiles', schema); // 同步导出模块,不要放在异步回调里 module.exports = { mongoose, db: mongoose.connection, model }; // 数据库连接逻辑单独执行 mongoose.connect(mongoUri, { dbName: "x" }).then(() => { const db = mongoose.connection; db.on('error', err => console.error(err)); }); - 如果业务要求必须等数据库连接成功后再执行操作,可以单独导出连接Promise,业务侧按需等待连接就绪即可:
// database.js 中导出连接Promise const connectPromise = mongoose.connect(mongoUri, { dbName: "x" }); // 模型注册、其余导出逻辑保持同步写法不变 module.exports = { mongoose, db: mongoose.connection, model, connectPromise }; // 业务侧使用 const { model, connectPromise } = require("../database"); connectPromise.then(() => { model.findOne(...).then(...) });
内容的提问来源于stack exchange,提问作者Zac Feng
相关产品推荐
相关产品推荐

