Mongoose创建对象时prizes.patterns嵌套数组数据丢失问题
Mongoose嵌套数组
patterns无法写入数据库问题 我在基于Mongoose模型创建Game对象时遇到了问题:prizes字段下的嵌套patterns数组始终为空,无法写入数据。无论是在构造函数中直接赋值prizes: currentGameConfig.prizes,还是后续执行newGame.prizes = prizes,prizes的其他属性(name、winAmount等)都能正常显示,但patterns数组始终是空的。
相关代码与配置
Mongoose模型定义
const GameSchema = mongoose.Schema({ type: String, roundId: String, userId: String, calloutNumbersCount: Number, tickets: [ { id: String, columns: [[Number]], }, ], prizes: [ { id: String, name: String, nameLocaleKey: String, winAmount: Number, patterns: [ { type: String, count: Number, }, ], }, ], ticketPrice: Number, boughtTicketIds: [String], ended: Boolean, });
控制器代码
function createGame(gameType, userId) { const currentGameConfig = config[gameType]; console.log("Controller"); currentGameConfig.prizes.map((el) => console.log(el.patterns)); const roundId = nanoid(LENGTH_OF_ROUND_ID); const game = new Game({ type: currentGameConfig.type, roundId, userId, calloutNumbersCount: currentGameConfig.callout.numbersCount, tickets: [ { id: 123, // temp columns: [[0]], // temp }, ], prizes: currentGameConfig.prizes, ticketPrice: currentGameConfig.tickets.price, boughtTicketIds: ["1", "2"], // temp ended: false, }); return game; }
路由中的创建逻辑
if (!game) { const newGame = gameController.createGame(type, userId); // newGame.prizes = currentGameConfig.prizes; Game.addGame(newGame, (err, game) => { if (err) { res.json({ success: false, message: err.message }); throw err; } return res.json({ roundId: newGame.roundId, }); }); }
当前游戏配置currentGameConfig
{ type: 'BINGO_75', name: 'Bingo 75', nameLocaleKey: 'GAMES.BINGO_75', prizes: [ { name: 'Prize 1', nameLocaleKey: 'PRIZES.BINGO_75.PRIZE_1', winAmount: 10, patterns: [Array] }, { name: 'Prize 2', nameLocaleKey: 'PRIZES.BINGO_75.PRIZE_2', winAmount: 10, patterns: [Array] }, { name: 'Prize 3', nameLocaleKey: 'PRIZES.BINGO_75.PRIZE_3', winAmount: 10, patterns: [Array] }, { name: 'Prize 4', nameLocaleKey: 'PRIZES.BINGO_75.PRIZE_4', winAmount: 10, patterns: [Array] }, { name: 'Full house', nameLocaleKey: 'PRIZES.BINGO_75.PRIZE_5', winAmount: 10, patterns: [Array] } ], tickets: { price: 10, quantity: 72, grid: { cols: [Object], rows: [Object] } }, callout: { numbersCount: 25 } }
排查细节
在Node.js中打印currentGameConfig.prizes里的patterns,展开后是有数据的:
[ {type: 'HORIZONTAL', count: 1}, {type: 'VERTICAL', count: 1}, {type: 'DIAGONAL', count: 1} ]
但最终存入数据库的Game对象中,patterns数组始终是空的,预期应该包含上述数据。
解决方案
方案1:为嵌套的patterns定义显式的子Schema
Mongoose对于深层嵌套的数组,显式定义子Schema能确保正确解析数据:
// 定义patterns的子Schema const PatternSchema = mongoose.Schema({ type: String, count: Number, }); // 定义prizes的子Schema const PrizeSchema = mongoose.Schema({ id: String, name: String, nameLocaleKey: String, winAmount: Number, patterns: [PatternSchema], }); // 重构GameSchema const GameSchema = mongoose.Schema({ type: String, roundId: String, userId: String, calloutNumbersCount: Number, tickets: [ { id: String, columns: [[Number]], }, ], prizes: [PrizeSchema], ticketPrice: Number, boughtTicketIds: [String], ended: Boolean, });
方案2:赋值时深拷贝配置数据
如果配置对象的patterns是引用类型,可能导致Mongoose无法正确识别,建议深拷贝后再赋值:
// 在控制器中修改prizes的赋值方式 const game = new Game({ // ...其他字段 prizes: JSON.parse(JSON.stringify(currentGameConfig.prizes)), // ...其他字段 });
方案3:手动初始化patterns数组
如果上述方法无效,可以手动遍历prizes,确保每个pattern都被正确初始化:
const processedPrizes = currentGameConfig.prizes.map(prize => ({ ...prize, patterns: prize.patterns.map(pattern => ({ type: pattern.type, count: pattern.count })) })); const game = new Game({ // ...其他字段 prizes: processedPrizes, // ...其他字段 });
内容的提问来源于stack exchange,提问作者Vladimir
相关产品推荐
相关产品推荐

