Fla*_*nix 1 schema enums mongoose mongodb node.js
我有一个Mongoose模式,它定义了给定对象可以拥有的一组可能值.
const mongoose = require("mongoose");
const COUNTRIES = ["ES", "PT", "US", "FR", "UK"];
const GENDERS = ["M", "F"];
const surveySchema = {
subject: { type: String, required: true },
country: { type: String, enum: COUNTRIES },
target: {
gender: { type: String, enum: GENDERS }
}
};
module.exports = new mongoose.Schema(surveySchema);;
module.exports.modSchema = surveySchema;
Run Code Online (Sandbox Code Playgroud)
ENUM我个人并不喜欢ENUM值,因为如果我添加另一个值ENUM,我必须重新编译整个应用程序并进行部署.
我想,ENUM如果性别不会改变,这不是问题.
但是,对于国家/地区,我的SQL端告诉我应该存储它们,因为如果您的业务增长,您可能会扩展到其他国家/地区.
我的问题在于,我不知道如何在模式层面告诉Mongoose,这些国家唯一允许的值必须是["ES", "PT", "US", "FR", "UK"].
我想我可以创建一个收集国家,但后来我缺乏如何连接它们的知识.我是否必须使用异步验证器?
你会如何应对ENUM可以改变的?
您可以使用管理面板向国家/地区集合添加更多国家/地区.正如您所说,COUNTRIES阵列可以增长,您可以使用另一个集合从管理面板按需添加更多国家/地区.
当您要在调查中添加/保存新记录时,您可以触发mongo的预保存挂钩进行验证.
假设我们有这样的国家的另一种模式.
{
countries: [String]
}
Run Code Online (Sandbox Code Playgroud)
以下是该方案的示例代码.
const mongoose = require("mongoose");
const GENDERS = ["M", "F"];
const surveySchema = {
subject: { type: String, required: true },
country: { type: String},
target: {
gender: { type: String, enum: GENDERS }
}
};
var Survey = new mongoose.Schema(surveySchema);
Survey.pre('save',function(next){
var me = this;
CountryModel.find({},(err,docs)=>{
(docs.countries.indexOf(me.country) >=0) ? next() : next(new Error('validation failed'));
});
});
Run Code Online (Sandbox Code Playgroud)
这样,您可以处理动态国家/地区添加,而无需更改国家/地区阵列并重新部署整个服务器.
使用自定义验证器
const mongoose = require("mongoose");
const GENDERS = ["M", "F"];
const surveySchema = {
subject: {
type: String,
required: true
},
country: {
type: String,
validate: {
isAsync: true,
validator: function(arg, cb) {
CountryModel.find({}, (err, docs) => {
if (err) {
cb(err);
} else {
cb(docs.countries.indexOf(arg) >= 0);
}
}
},
message: '{VALUE} is not a valid country'
}
},
target: {
gender: { type: String, enum: GENDERS }
}
};
Run Code Online (Sandbox Code Playgroud)
在回调中保存调查数据时会出错.
ServeyModel.save((err,doc)=>{
if(err){
console.log(err.errors.country.message);
//Error handle
}else {
//TODO
}
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8656 次 |
| 最近记录: |