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);
}
});