Mongoose嵌套Detail Schema报错:类型路径值未定义,求解决方案
解决Mongoose中嵌套单个Schema时的TypeError错误
错误原因
你的代码报错是因为Detail.js导出的是Mongoose模型对象,而非Schema本身,且在User.js中错误地尝试通过detailSchema.Schema(大写S)获取Schema——模型对象的Schema属性是小写的schema,所以你拿到的是undefined,导致Mongoose无法识别嵌套字段的类型。
两种修正方案
方案一:直接导出Detail的Schema(推荐)
修改Detail.js,直接导出定义好的Schema,而非模型(如果需要单独使用Detail模型,可以额外导出):
const mongoose=require("mongoose"); const Schema=mongoose.Schema; const detailSchema=new Schema({ firstname:{type:String,required:true}, lastname:{type:String,required:true}, telephone:{type:Number,required:true}, hostel:{type:String,required:true}, hostelFees:{type:String,required:false}, roomNo:{type:String,required:true}, },{timestamps:true}); // 直接导出Schema module.exports = detailSchema; // 若需单独使用Detail模型,可追加: // module.exports.DetailModel = mongoose.model("Details", detailSchema);
然后修改User.js,直接使用导入的Schema:
const mongoose=require("mongoose"); const Schema=mongoose.Schema; const complaintSchema=require("./Complaint"); // 现在导入的是Detail的Schema对象 const detailSchema=require("./Detail"); const userSchema=new Schema({ username:{type:String,required:true,unique:true}, email:{type:String,required:true,unique:true}, password:{type:String,required:true}, detailsFilled:{type:Boolean,default:false}, // 直接使用detailSchema作为类型 details:{type:detailSchema}, complaints:{type:[complaintSchema.Schema]} },{timestamps:true}); module.exports=mongoose.model("Users",userSchema);
方案二:从已导出的模型中提取Schema
如果需要保留Detail.js中的模型导出,可在User.js中从模型对象里获取Schema(注意是小写的schema属性):
const mongoose=require("mongoose"); const Schema=mongoose.Schema; const complaintSchema=require("./Complaint"); // 导入Detail模型 const detailModel=require("./Detail"); // 从模型中提取Schema const detailSchema=detailModel.schema; const userSchema=new Schema({ username:{type:String,required:true,unique:true}, email:{type:String,required:true,unique:true}, password:{type:String,required:true}, detailsFilled:{type:Boolean,default:false}, // 使用提取到的Schema details:{type:detailSchema}, complaints:{type:[complaintSchema.Schema]} },{timestamps:true}); module.exports=mongoose.model("Users",userSchema);
额外说明
- 如果你不需要单独操作Detail集合(比如不需要单独查询、创建Detail文档),方案一更简洁,因为嵌套Schema不需要单独的模型。
- 每个用户对应单个Detail对象的需求,通过
details:{type:detailSchema}即可实现,不需要用数组包裹。
内容的提问来源于stack exchange,提问作者tdcoder
相关产品推荐
相关产品推荐

