I have two models. One is for Patient and Another one is for Lab Test Report. While inserting a record in Report Model i am getting patient Id by using a common field contactno and storing it in Report model in a field patient which is referring to ObjectId of Patient model.
In Patient model there is a array of reports which on populate should show all reports associate with patient. below are my models and Controllers.
**Patient Model **
const mongoose = require("mongoose")
const Reports = require('./reportModel')
const patientSchema = mongoose.Schema({
name:{
type:String,
required:[true,"Please Enter Patient Name"]
},
gender:{
type:String,
required:[true, "Please Enter Patient Gender"]
},
age:{
type:Number,
required:[true, "Please Enter Patient Age"]
},
address:{
type:String,
required:[true, "Please Enter Patient Adress"]
},
dateOfBirth:{
type:String,
required:[true, "Please Enter Patient Date of Birth"]
},
email:{
type:String,
required:[true, "Please Enter Patient Email"]
},
contact:{
type:Number,
required:[true, "Please Enter Patient contact"]
},
reports: [{
type: mongoose.Schema.ObjectId,
ref: "Report",
}],
emergContact:{
type:Number,
required:[true, "Please Enter Patient Emergency Contact"]
},
weight:{
type:Number,
default:1
},
reviews: [
{
user: {
type: mongoose.Schema.ObjectId,
ref: "User",
required: true,
},
name: {
type: String,
required: true,
},
rating: {
type: Number,
required: true,
},
comment: {
type: String,
required: true,
},
},
],
user: {
type: mongoose.Schema.ObjectId,
ref: "User",
required: true,
},
createdAt:{
type:Date,
default:Date.now
}
})
module.exports = mongoose.model("Patient",patientSchema)
**Reports model **
const mongoose = require("mongoose");
const validator = require("validator");
const reportSchema = mongoose.Schema({
patient: {
type: mongoose.Schema.ObjectId,
ref: "Patient",
required: true,
},
type:{
type: String,
required: [true, "Please Enter Your testType"],
},
name:{
type:String,
required:[true, "Please enter Type of test"]
},
contact:{
type:Number,
required:[true, "Must enter valid contact number of patient"]
},
remarks:{
type:String,
}
})
module.exports = mongoose.model("Report", reportSchema);
Below is report controller which saves data in report model and also stores Object Id of Patient by querying phone number
exports.createReport = catchAsyncErrors(async(req,res,next)=> {
const patient = await Patient.findOne({contact:req.body.contact})
const newreq = {patient:patient._id,
type:req.body.type,
name:req.body.name,
contact:req.body.contact,
remarks:req.body.remarks
}
const report = await Report.create(newreq)
res.status(200).json({
success:true,
report
})
}
)
Output from report query
{
"success": true,
"report": {
"_id": "652dc1e07acd6e401e4d3da5",
"patient": "651e3fa49b84a8a8c8532fa1",
"type": "Skin Test",
"name": "Skin Examination",
"contact": 532531216,
"remarks": "Should use sun block",
"__v": 0
}
}
Single Patient query
exports.getPatientDetails = catchAsyncErrors(
async(req,res,next)=>{
const patient = await Patient.findById(req.params.id).populate({path:'Report',strictPopulate:false}).exec()
if(!patient){
return next(new ErrorHandler("Patient Not Found",404))
}
res.status(200).json({
success:true,
patient
})
}
)
{
"success": true,
"patient": {
"reports": [],
"_id": "651e3fa49b84a8a8c8532fa1",
"name": "Patient 3",
"gender": "Male",
"age": 65,
"address": "Shahdara Lahore",
"dateOfBirth": "07-05-1945",
"email": "ptt@gmail.com",
"contact": 532531216,
"emergContact": 55666666,
"weight": 90,
`"
createdAt": "2023-10-05T04:46:28.810Z",
"__v": 0,
"reviews": []
}
}
reports array is empty whereas according to my understanding it should show array of reports associated with specified patient.
I tried to search online regarding mongodb table joins and population.
Well i am now pasting code of both controllers to be helpful for others. I resolved this issue by making below mentioned changes.
Report Controller
exports.createReport = catchAsyncErrors(async (req, res, next) => {
const patient = await Patient.findOne({ contact: req.body.contact })
const newreq = {
patient: patient._id,
type: req.body.type,
name: req.body.name,
contact: req.body.contact,
remarks: req.body.remarks
}
const report = await Report.create(newreq)
newpatient = await Patient.findOneAndUpdate(
{ _id: report.patient },
{ runValidators: false, context: 'query' },
)
await newpatient.reports.push(report._id)
await newpatient.save()
res.status(200).json({
success: true,
report
})
})
Patient Controller
exports.getPatientDetails = catchAsyncErrors(async (req, res, next) => {
let patient = await Patient.findById(req.params.id).populate(
{ path: 'reports', strictPopulate: false }
)
if (!patient) {
return next(new ErrorHandler("Patient Not Found",404))
}
res.status(200).json({
success: true,
patient
})
})
Now on every new report creation by using contact number it populates ObjectId on both sides and when patient is accessed it also retrieves associated reports.