[英]How to modify mongoose schema dynamically, i have to add dynamic fields that are not defined in initial mongoose Schema
[英]How to add Schema Dynamically in 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});
}
});
將您的設置字段定義為Schema.Types.Mixed ,以便您可以在其中設置任何類型的字段,例如Number , String , Array , Date , Boolean
..etc
const mongoose = require('mongoose');
const testSchema = new mongoose.Schema({
label: {
required: 'please enter label',
trim: true,
type: String
},
url: {
type: String,
trim: true,
},
settings: {
type:Schema.Types.Mixed ,
default: {}
}
}, {
timestamps: true, strict: false
});
module.exports = mongoose.model('test', testSchema);
保存文檔時:
app.post('/save',function(req,res){
var setting = {};
setting.age= req.body.age;
setting.name= req.body.name;
var test = new Test({
test.label: req.body.label;
test.url :req.body.url;
test.setting: setting
});
test.save(function(err){
if(err) {return res.json(err);}
else{ res.json({status:'success',message:'saved.'});}
});
});
以防萬一有人在 NestJS 和 schemaFactory 上遇到這個問題,我就是這樣解決的:
...
@Schema({ strict: false })
export class Content {}
@Schema()
export class Deadletter extends Document {
@Prop({type: Header})
header: Header;,
@Prop({type: Metadata})
_metadata?: Metadata;
@Prop({type: Content})
content: any;
}
export const deadLetterFullSchema = SchemaFactory.createForClass(Deadletter);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.