You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 17:45:48