node.js - 如何在 MongoDB/Mongoose 中动态添加模式
问题描述
我想创建一个由用户定义的数据库,每个用户都可以拥有自己的数据库风格。所以我使用strict: false
了但是现在的问题是我不能让用户type
在模型下定义每个模式
例子
const mongoose = require('mongoose');
const testSchema = new mongoose.Schema({
label: {
required: 'please enter label',
trim: true,
type: String
},
url: {
type: String,
trim: true,
},
settings: {} //User defined
}, {
timestamps: true, strict: false
});
module.exports = mongoose.model('test', testSchema);
在上述情况下,我希望设置由用户定义,例如,
{
"label": "About Us",
"url": "www.google.com",
"settings": {
"name": {
"type": "String", //Problem is Here, i can't send datatype directly
"required": true
},
"age": {
"type": "Number",
"required": true,
"enum": [10, 12]
}
}
}
所以请告诉我,我怎样才能让用户定义模式的类型?
解决方案
strict: true
并不意味着您可以将任何内容传递给settings
字段。
这意味着您的架构格式是动态的 - 您可以在文档中包含未在架构中定义的意外字段名称。
回答您的问题:
好像您想要子文档,让我们制作另一个架构并将其附加为类型:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const types = Schema.Types;
const testSettingsSchema = new Schema({
name: {
type: types.String,
required: true
},
age: {
type: types.Number,
required: true
enum: [10, 12]
}
},
{
_id : false,
timestamps: false,
strict: false
});
const testSchema = new Schema({
label: {
required: 'please enter label',
trim: true,
type: types.String
},
url: {
type: types.String,
trim: true,
},
settings: {
type: testSettingsSchema,
required: true
}
},
{
timestamps: true,
strict: true
});
module.exports = mongoose.model('test', testSchema);
但是为了获得更大的灵活性并避免创建大test
文档(因为用户可能会推送不可预测的大对象),请创建另一个模式:testSettings
指向test_settings
集合并制作settings
要引用的字段:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const types = Schema.Types;
const testSettingsSchema = new Schema({
name: {
type: types.Mixed
},
age: {
type: types.Mixed
}
},
{
collection: 'test_settings',
timestamps: false,
strict: false // tells to mongoose that schema may "grow"
});
mongoose.model('testSettings', testSettingsSchema);
const testSchema = new Schema({
label: {
required: 'please enter label',
trim: true,
type: types.String
},
url: {
type: types.String,
trim: true,
},
settings: {
type: types.ObjectId,
ref: 'testSettings'
default: null
}
},
{
collection: 'tests',
timestamps: true,
strict: true
});
module.exports = mongoose.model('test', testSchema);
将其创建为:
const Test = mongoose.model('test');
const TestSettings = mongoose.model('testSettings');
app.post('/tests', async (req, res) => {
try {
const testSettings = await TestSettings.create(req.body.settings);
const test = new Test(req.body);
test.settings = testSettings._id;
await test.save();
res.status(201).send({_id: test._id});
}
catch(error) {
res.status(500).send({message: error.message});
}
});
并在请求时间得到它:
const Test = mongoose.model('test');
app.get('/tests/:id', async (req, res) => {
try {
const test = await Test.findById(req.params.id)
.populate('settings')
.lean();
res.status(200).send(test);
}
catch(error) {
res.status(500).send({message: error.message});
}
});
推荐阅读
- mysql - 使用'table.column = t.column'如何有效(当t是table的缩写时)
- php - 在引导按钮单击时更新数据库
- node.js - 运行 Ionic 4 时找不到模块 node-sass
- react-native - React 导航错误:在调用“reduxfiyNavigator”之前,请调用“createReactNavigationReduxMiddleware”,
- swift - 在 Swift 中完成异步函数执行后,在尾随闭包之外获取一个完全填充的数组
- laravel - 在 laravel 中使用 eloquent 连接 2 个数据库表
- rust - 最小期货回调示例中的“预期生命周期参数”错误?
- java - 如何在heroku中使用angular2代码部署Spring Boot
- groovy - Groovy 中 propertyMissing 方法的静态版本是什么?
- asp.net-core - .NET 核心自定义和默认绑定相结合