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

如何在Mongoose中为对象定义带动态键的统一嵌套Schema?

在Mongoose中定义动态键名的嵌套对象Schema

当然可以实现,这里有两种靠谱的方案,其中第一种是Mongoose官方推荐的最佳实践:

方案1:用Map类型(最简洁)

Mongoose的Map类型就是为这种「键名动态、值结构统一」的场景设计的,直接指定of为你的Nested Schema就行:

const Nested = new mongoose.Schema({
  name: String,
});

const Main = new mongoose.Schema({
  name: String,
  nested: {
    type: Map,
    of: Nested // 强制所有值都遵循Nested的结构
  }
});

这样定义后,nested就是个普通对象,你可以随便加en、bg这类动态键,每个键对应的值都会自动被Mongoose按照Nested Schema验证、处理。

举个使用例子:

const testDoc = new MainModel({
  name: "Demo",
  nested: {
    en: { name: "English" },
    bg: { name: "Bulgarian" },
    // 后续加任意键都没问题,只要值符合Nested结构
  }
});

await testDoc.save(); // 完全合法

方案2:用Mixed类型加自定义验证

如果需要更细粒度的控制,也可以用Schema.Types.Mixed配合自定义验证函数,手动确保所有值都符合Nested的结构:

const Nested = new mongoose.Schema({
  name: String,
});

const Main = new mongoose.Schema({
  name: String,
  nested: {
    type: Schema.Types.Mixed,
    validate: {
      validator: function(obj) {
        // 先判断是不是合法对象
        if (typeof obj !== 'object' || obj === null) return false;
        // 遍历每个键,验证值的结构
        for (const key in obj) {
          const val = obj[key];
          if (!val || typeof val.name !== 'string') {
            return false;
          }
        }
        return true;
      },
      message: 'nested对象的每个值必须符合Nested Schema的结构'
    }
  }
});

这种方法需要自己写验证逻辑,不如Map省心,所以优先选第一种方案。

补充说明

  • Map类型存储到MongoDB里就是普通的BSON对象,和你原来的写法存储结构完全一致,查询、更新操作和普通对象没区别。
  • 如果要给动态键加索引,可以用MongoDB的通配符索引(3.6及以上版本支持),或者针对特定键单独创建索引。

内容的提问来源于stack exchange,提问作者dako

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 14:52:24