Home > Software design >  Dynamic Mongoose Field Type
Dynamic Mongoose Field Type

Time:03-09

I am developing an app where a user could store his model on a database using mongoDB and mongoose. Taken from mongoose tutorial the type of the field has to be defined. For example here we have to define that the name is a string.

const personSchema = new mongoose.Schema({
  name: String
});
const Person = mongoose.model('Person', personSchema);

Is there any way to make it dynamic to user's input. I want to create a form where a user will enter a field name and select one of the field types that Mongoose offers [String,Number,Date etc], but I cannot figure any way to implement it. To be honest I don't know even if this is a good approach. An alternative would be to pass everything as a String and serialise the input in order to store it. I want to achieve something like that:

const {fieldName,fieldType} = userInput;

const customSchema = new mongoose.Schema({
  fieldName: fieldType
});
const CustomModel = mongoose.model('CustomSchema', customSchema);

Is this possible or should I implement another approach? An alternative would be to pass everything as a String and serialise the input in order to store it.

Thank you in advance!

CodePudding user response:

If I understand you correctly it should work like that:

  • User defines the model to store
  • Schema is created using the data provided by the user
  • User can pass the data to store using the previously created model which will validate the user's input later

In fact, I'm working on a project that has the same functionality. Here is how we did it.

  • A user sends the model and we store it as a string since we need to have the ability to create the model once again.

  • When the user passes new data to store using the created model we get the string from mongo and parse it to create the schema. This operation is relatively easy (but depends on what you want to achieve as it can get tricky if you want to have some advanced validation) as you have to just create an object with correct values from mongoose. Something like this for every field that the user has defined.

    export const fieldConverter = ({name, type}) => {
       switch (type) {
         case 'String':
           return { [name]: String };
         case 'Number':
           return { [name]: Number };
        ...
    }
    

    When you have your object ready then you can create a model out of it. The line with accessing your model from mongoose.models is important as the mongoose will cache the model and throw an error if you try to create it once again.

    const DatasetModel =
      mongoose.models["your-model-name"] ??
      mongoose.model("your-model-name", new mongoose.Schema(schema));
    
  • Now when you have the model the rest is just like with the normally created one.

This approach worked for us so I'm adding this as inspiration maybe it will help you. If you have any specific questions about the implementation feel free to ask I will be happy to help.

There is also a Mixed type in mongoose if you don't need the validation later. You can check it here: https://mongoosejs.com/docs/schematypes.html#mixed

CodePudding user response:

You can use Schema.Types.Mixed, An "anything goes" SchemaType. Mongoose will not do any casting on mixed paths.

let customSchema = new Schema({custom: Schema.Types.Mixed})

Read more about it here

  • Related