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

Mongoose如何根据国家属性值动态设置对应城市的枚举选项?

Mongoose 国家-城市联动枚举实现方案

因为Mongoose Schema的enum配置是静态定义的,无法直接读取同文档其他字段的动态值实现联动,你可以通过自定义验证器实现城市枚举随国家动态校验,具体实现如下:

const mongoose = require('mongoose');

// 抽离公共常量,避免重复编码
const COUNTRY_ENUM = ['USA', 'GB', 'CA', 'BR'];
const CITIES_MAP = {
  USA: ['New York', 'Los Angeles', 'Chicago'],
  GB: ['London', 'Manchester', 'Birmingham'],
  CA: ['Toronto', 'Vancouver', 'Montreal'],
  BR: ['São Paulo', 'Rio de Janeiro', 'Brasília']
};

const questionSchema = new mongoose.Schema({
  address: {
    country: {
      type: String,
      required: true,
      enum: COUNTRY_ENUM
    },
    city: {
      type: String,
      required: true,
      // 用自定义验证器实现动态枚举校验
      validate: {
        validator: function(cityVal) {
          // 此处不能用箭头函数,否则this无法指向当前文档实例
          const allowedCities = CITIES_MAP[this.address.country];
          // 校验当前填写的城市是否属于对应国家的城市列表
          return allowedCities?.includes(cityVal) ?? false;
        },
        // 校验失败的提示信息
        message: props => `${props.value} 不属于所选国家的合法城市列表`
      }
    }
  }
});

const Question = mongoose.model('Question', questionSchema);

注意事项

  • 验证器必须使用普通函数声明,不能用箭头函数,否则会丢失当前文档实例的this指向,无法读取已填写的country值
  • 如果你使用findOneAndUpdate、updateMany这类更新操作,需要手动开启验证器才能触发城市校验,示例写法:
    Question.findOneAndUpdate(
      { _id: 文档ID },
      { 'address.city': 'London' },
      // 开启运行验证器,否则自定义校验不会生效
      { runValidators: true, new: true }
    )
    
  • 如果国家为非必填字段,可以在验证器中增加this.address.country的非空判断,适配国家未填写时的校验逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 16:09:02