Home > Enterprise >  Overriding Mongoose _id and using properties directly from the schema
Overriding Mongoose _id and using properties directly from the schema

Time:08-13

I need to create a patient model and override the _id property. I know I can override it by writing a schema like so:

const PatientSchema: Schema = new Schema({
    _id: {type: String, required: true},
    name: { type: String, required: true },
    surname: { type: String, required: true },
    provider: { type: Schema.Types.ObjectId, ref: "Provider" },
});

Is there a way to define the _id property inside the schema to reference the name surname properties?:

_id: name surname, (?)

or do I have to explicitly define it when creating and saving a new model?:

const patient = new Patient();
patient._id = name surname;

Also, what should I consider if patients have the same name and surname? What is considered best practice in this case if the _id needs to = name surname?

Thanks

CodePudding user response:

you could use mongoose pre-save middleware in your schema

Basically, middlewares are functions that are called during the execution of a model query/method.

there are 2 types of middleware :

  • "pre" middlewares that are executed before the query
  • "post" middlewares that are executed after the query.

syntax :

schema.pre([method], function (next) {
    console.log("pre middleware")
    next();
});

schema.post([method], function (next) {
    console.log("post middleware")
    next();
});

/*[method] can be 
"save","updateOne","findOne","findOneAndUpdate",etc...*/
//"pre" will always be executed before "post"

And depending on the method you are going to use, middlewares can change in the value of "this", there are 4 types of these:

  • where "this" refers to the document E.g."save"
  • where "this" refers to the query E.g."findOne"
  • where "this" refers to an aggregate E.g." aggregate"
  • where "this" refers to the model. E.g. "insertMany"

Solution :

const PatientSchema = new Schema({
    _id: { type: String },
    name: { type: String, required: true },
    surname: { type: String, required: true },
    provider: { type: Schema.Types.ObjectId, ref: "Provider" },
});

//will change _id before save 
PatientSchema.pre("save", async function (next) {
    try {
     const patient = this;  //the target document  
     patient._id = patient.name   " "   patient.surnam
     next()

    }
    catch (err) { next(err) }

});
module.exports = model("Patients", PatientSchema);

and when you create a patient it will have the id based on the combination of their first and last name

const patient = new Patient({
  name: "John",
  surname: "smith"
})
await patient.save();

result : {
  _id: "John smith ";
  name: "John";
  surname: "smith";
  __v: 0;
}

[ Edit ] if you want your id to be unique you could create an ObjectId and concatenate it to the final id

  const { ObjectId } = require("mongodb");
  
  PatientSchema.pre("save", async function (next) {
    try {
      const patient = this; //the target document
      const objectId = ObjectId();
      patient._id = `${patient.name} ${patient.surname}  ${objectId}`;
  
      next();
    } catch (err) {
      next(err);
    }
  
  });

  • Related