使用TypeScript操作Mongoose时为何触发MissingSchemaError?
MissingSchemaError: Schema hasn't been registered for model "Portfolio" 问题解决
问题原因
Mongoose处理关联查询(populate)时,要求被引用的模型必须已经在Mongoose的全局模型注册表中完成注册。出现该错误的核心原因:
- 执行User模型的
populate('portfolios')操作时,Portfolio模型还未被加载注册,Mongoose找不到对应的Schema。 - 即使导入了Portfolio模型,若代码中未实际使用导出的变量,部分模块打包工具或TypeScript的树摇优化会跳过该模块执行,导致模型注册代码未运行。
正确解决方法
1. 在入口文件统一预加载所有模型
在应用启动的入口文件(如server.ts/app.ts)中,先导入所有模型,再初始化数据库连接和路由,确保所有模型在查询前完成注册:
// server.ts // 第一步:先导入所有模型 import './models/User.model'; import './models/Portfolio.model'; // 第二步:初始化数据库和其他服务 import mongoose from 'mongoose'; import express from 'express'; const app = express(); // 连接数据库 mongoose.connect('your-mongodb-uri') .then(() => console.log('DB connected')) .catch(err => console.error('DB connection error', err)); // 注册路由等后续逻辑 // ...
2. 在User模型中显式导入Portfolio
在User.model.ts中直接导入Portfolio模型,强制触发其模块执行,完成模型注册:
// User.model.ts import mongoose, {Types, Schema} from "mongoose"; // 显式导入Portfolio模型,确保模块代码被执行 import './Portfolio.model'; export interface IUser { name: string, portfolios: Types.ObjectId[], } export interface IUserModel extends IUser, Document {} const userSchema = new Schema<IUserModel>({ name: { type: String, required: true, trim: true }, portfolios: [{ type: mongoose.Schema.Types.ObjectId, ref: "Portfolio" }], }) export const User = mongoose.model<IUserModel>('User', userSchema)
若需要用到Portfolio的类型,也可改为导入具体导出项:
import { Portfolio } from './Portfolio.model';
3. 检查导入路径的正确性
确保User模型中导入Portfolio的路径正确,注意TypeScript对文件路径大小写敏感(比如Portfolio.model.ts和portfolio.model.ts是不同文件),避免因路径错误导致模块未加载。
内容的提问来源于stack exchange,提问作者Thanh Dao Duc
相关产品推荐
相关产品推荐

