NextJS中Mongoose子文档未保存问题排查
问题
希望在NextJS中使用Mongoose保存包含多个子文档的Scores文档,子文档包含player和score字段。
我的Schema代码
import { Schema, model, models } from "mongoose"; const ScoreSchema = new Schema({ creator: { type: Schema.Types.ObjectId, ref: 'User', }, scores_to_save: [ { player: { type: String }, score: { type: String } } ] }); const Score = models.Score || model( 'Score', ScoreSchema ); export default Score;
我的API路由代码
import { connectToDB } from "@utils/database"; import Score from "@models/score"; export const POST = async ( req ) => { const { userId, scores } = await req.json(); try { await connectToDB(); const newScores = new Score({ creator: userId }); // 目前手动插入数据用于测试 newScores.scores_to_save = [ { player: 'my name', score: '5' }, { player: 'your name', score: '6' } ]; console.log('TO SAVE Document: ', newScores ); await newScores.save(); return new Response( JSON.stringify( newScores ), { status: 201 } ); } catch (error) { return new Response( "Failed to create a new Scores.", { status: 500 } ); } }
控制台输出
TO SAVE Document: { creator: new ObjectId("652af415729e8d8a59b2202f"), _id: new ObjectId("6532cfcd4c76ca7d258d3f0d") }
当前问题:控制台输出完全忽略newScores.scores_to_save部分,无报错,但数据库中仅保存了creator和_id的值,请问遗漏了什么?
解决方案
核心原因
大概率是Next.js中Mongoose模型的缓存问题:你修改Schema添加scores_to_save字段后,由于models.Score已经存在于缓存中,新的Schema没有被重新加载,导致Mongoose认为该字段未定义,自动忽略。
解决步骤
清除Next.js缓存并重启服务
删除项目根目录下的.next文件夹,然后重启开发服务器,确保新的Schema被正确加载。直接在创建文档时传入子文档数组
避免后续赋值,直接在new Score()构造函数中传入完整数据,确保Mongoose能识别所有字段:const newScores = new Score({ creator: userId, scores_to_save: [ { player: 'my name', score: '5' }, { player: 'your name', score: '6' } ] });开发环境临时跳过模型缓存(可选)
在模型文件中添加判断,开发环境下删除已缓存的模型,确保每次都使用最新Schema:import { Schema, model, models } from "mongoose"; const ScoreSchema = new Schema({ creator: { type: Schema.Types.ObjectId, ref: 'User' }, scores_to_save: [ { player: { type: String }, score: { type: String } } ] }); // 仅开发环境使用,生产环境保留原缓存逻辑 if (process.env.NODE_ENV === 'development') { delete models.Score; } const Score = models.Score || model('Score', ScoreSchema); export default Score;
额外调试技巧
如果控制台打印仍不显示scores_to_save,可以使用toObject()方法输出完整文档对象:
console.log('TO SAVE Document: ', newScores.toObject());
内容的提问来源于stack exchange,提问作者Jose Molina
相关产品推荐
相关产品推荐

