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