如何定义所有属性均为String类型的任意键Mongoose Schema?
当然可行呀!有两种常用的方案能满足你的需求,我给你一步步讲清楚:
实现方案一:使用Mongoose Map类型(推荐)
Mongoose专门提供了Map类型来处理动态键的场景,而且可以精准指定所有值的类型为String,既规范又安全。
示例代码:
const mongoose = require('mongoose'); // 定义Schema,用Map来承载任意键值对,值的类型固定为String const dynamicStringSchema = new mongoose.Schema({ dynamicFields: { type: Map, of: String } }); // 生成Model const DynamicModel = mongoose.model('Dynamic', dynamicStringSchema);
使用的时候,你可以给dynamicFields添加任意名称的键,所有值都会被Mongoose验证为String类型:
// 创建文档实例 const doc = new DynamicModel({ dynamicFields: { any_key1: '我是字符串1', user_nickname: '小码农', random_key_xyz: '随便起的键名' } }); // 保存到数据库 await doc.save();
这种方案的优势是结构清晰,把固定字段和动态字段分开,Mongoose会自动校验动态字段的类型,查询和维护也更方便。
实现方案二:关闭严格模式并全局设置字段类型
如果你希望动态键直接放在文档的根层级(而不是嵌套在某个字段里),可以关闭Schema的strict模式,同时设置所有未知键的类型为String。
示例代码:
const mongoose = require('mongoose'); // 初始化空Schema,关闭严格模式以允许任意键 const dynamicRootSchema = new mongoose.Schema({}, { strict: false }); // 全局设置:所有未提前定义的键,值的类型都为String dynamicRootSchema.path('*').type(String); // 生成Model const DynamicRootModel = mongoose.model('DynamicRoot', dynamicRootSchema);
使用示例:
const doc = new DynamicRootModel({ any_key1: '直接放在根节点的字符串', email: 'test@example.com', whatever_you_want: '没问题' }); await doc.save();
这种方案更灵活,但要注意:关闭strict模式后,Mongoose不会自动过滤不符合类型的数据,但我们通过path('*').type(String)设置了类型校验,如果传入非String类型的值,Mongoose会尝试转换,转换失败则会抛出错误。
内容的提问来源于stack exchange,提问作者Syd'ly Didou
相关产品推荐
相关产品推荐

