Search code examples
mongodbmongoosemongodb-querymongoose-schemamongoose-populate

How to populate an field in array of Mongooese?


I have a collection schema like this:

const PrescriptionSchema = new Schema({
    patientId:{type: mongoose.Schema.ObjectId, ref: 'User'},
    prescriptionName: String,
    prescriptionNote: String,
    prescriptionDate: Date,
    diseaseId: {type: mongoose.Schema.ObjectId, ref: 'Diseases'},
    drugs: [{
        drugcateId:{type: mongoose.Schema.ObjectId, ref: 'DrugCategory'},
        quantity: Number,
        howtouse: String
    }],
    is_deleted: {type: Boolean, default: false},
    createdBy: {type: mongoose.Schema.ObjectId, ref: 'User'}
}, {
        timestamps: true,
        collection: 'prescriptions'
    }
);
export default mongoose.model('prescriptions', PrescriptionSchema );

Note that in this collection I have an array of "drugs", this is an array of drug that I get from 'DrugCategory', in each drug I have quantity and howtouse..so that I group it (drugCateId, quantity, howtouse) in drugs array. When I find a prescription, I want to populate drugCateId inside drugs array. How can I do it? Below is my current code:

async findOne(req, res){
        const { id } = req.params;
       await Prescriptions.
            findOne({ is_deleted: false, _id: id}).
             .populate(
               {
                 path: 'drugs',
                   populate: {
                     path: 'drugCateId',
                     model: 'DrugCategory'
                   }
               }).
            exec(function (err, data) {
              if (err) return handleError(err);
              res.send(data)
            });
      }

But it's not work. Below is my result:

{
    "is_deleted": false,
    "_id": "5f32768a06693a520806717d",
    "patientId": "5c80930d447df7735138693e",
    "prescriptionName": "Prescription for you",
    "prescriptionNote": "Please drink follow doctor",
    "prescriptionDate": "2020-07-08T00:00:00.000Z",
    "diseaseId": "5f22a6d600980c081ca9e14f",
    "drugs": [
        {
            "_id": "5f32768a06693a5208067181",
            "drugcateId": "5f23deca04e3150a48632229", // How can I populate this one?
            "quantity": 10,
            "howtouse": "drink 2 times after meal everyday"
        },
        {
            "_id": "5f32768a06693a5208067180",
            "drugcateId": "5f23deca04e3150a48632233", // How can I populate this one?
            "quantity": 10,
            "howtouse": "drink 2 times after meal everyday"
        },
        {
            "_id": "5f32768a06693a520806717f",
            "drugcateId": "5f23deca04e3150a48632234", // How can I populate this one?
            "quantity": 10,
            "howtouse": "drink 2 times after meal everyday"
        },
        {
            "_id": "5f32768a06693a520806717e",
            "drugcateId": "5f23deca04e3150a4863224a", // How can I populate this one?
            "quantity": 10,
            "howtouse": "drink 2 times after meal everyday"
        }
    ],
    "createdBy": "5d1cd947231ceb95b8838c1b",
    "createdAt": "2020-08-11T10:44:26.842Z",
    "updatedAt": "2020-08-11T10:44:26.842Z",
    "__v": 0
}

I hope you understand my issue, please take a look. Thanks you


Solution

  • Your current version does not match your schema. It suggest you want to populate both drugs and drugs.drugcateId. But here drugs are embedded directly and not references to documents in another collection, so it's not possible to populate():

     .populate({
         path: 'drugs',  // this assumes drugs are objectIds: [{ type: ObjectId, ref: 'Drug' }]
         populate: {
           path: 'drugCateId',
           model: 'DrugCategory'
         }
       })
    

    Instead, you should be able to use dot-notation for arrays:

    .populate({ path: "drugs.drugcateId" })
    

    or short

    .populate("drugs.drugcateId")