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

如何在Mongoose中创建依赖于其他枚举的关联枚举?

为Mongoose Schema的专科关联对应亚专科枚举的实现方案

需求背景

你现有Mongoose Schema如下:

const doctorSchema = new mongoose.Schema(
{
    specialty: {
        type: String,
        required: false
    },
    subspecialty: {
        type: String,
        required: false
    }
}

每位医生拥有一个专科(如心脏病学家cardiologist、神经学家neurologist),亚专科需依赖所属专科——比如神经学家可选神经危重症护理neurocritical care,但心脏病学家不能选该亚专科。你已定义专科枚举:

enum specialty {
    cardiologist = 'cardiologist',
    neurologist = 'neurologist'
}

需要为每个专科设置专属的亚专科列表。

实现方案

1. 定义专科与亚专科的映射枚举

先创建一个映射对象,把每个专科对应的合法亚专科枚举关联起来:

// 定义各专科对应的亚专科枚举集合
const subspecialtiesMap = Object.freeze({
  cardiologist: Object.freeze({
    INTERVENTIONAL: 'interventional cardiology',
    ELECTROPHYSIOLOGY: 'clinical electrophysiology',
    PREVENTIVE: 'preventive cardiology'
  }),
  neurologist: Object.freeze({
    NEUROCRITICAL: 'neurocritical care',
    NEUROLOGY_EP: 'clinical neurophysiology',
    MOVEMENT_DISORDERS: 'movement disorders'
  })
});

// 全局专科枚举(优化为冻结对象避免意外修改)
const Specialty = Object.freeze({
  CARDIOLOGIST: 'cardiologist',
  NEUROLOGIST: 'neurologist'
});

2. 在Schema中添加自定义验证逻辑

利用Mongoose的validate钩子,对subspecialty做关联性校验,确保它属于当前specialty对应的合法列表:

const doctorSchema = new mongoose.Schema({
  specialty: {
    type: String,
    enum: Object.values(Specialty),
    required: false
  },
  subspecialty: {
    type: String,
    required: false,
    validate: {
      validator: function(value) {
        // 无专科时,亚专科必须为空
        if (!this.specialty) return !value;
        // 获取当前专科对应的合法亚专科数组
        const validSubs = Object.values(subspecialtiesMap[this.specialty]);
        // 亚专科存在时必须在合法列表内,为空则直接通过
        return !value || validSubs.includes(value);
      },
      message: props => `${props.value} 不属于当前专科允许的亚专科范围`
    }
  }
});

3. 可选:封装工具函数简化业务调用

如果需要在业务代码中快速获取某专科的合法亚专科,可以封装一个工具函数:

function getValidSubs(specialty) {
  return subspecialtiesMap[specialty] ? Object.values(subspecialtiesMap[specialty]) : [];
}

// 使用示例
getValidSubs(Specialty.NEUROLOGIST);
// 返回 ["neurocritical care", "clinical neurophysiology", "movement disorders"]

关键说明

  • 用Object.freeze冻结枚举对象,避免业务代码意外修改枚举值,保证数据一致性。
  • 验证逻辑覆盖了无专科时亚专科必须为空的边界场景,避免产生无效数据。
  • 后续新增专科或亚专科时,只需在subspecialtiesMap和Specialty中补充对应项,无需修改Schema核心结构。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 11:40:31