Search code examples
javascriptnode.jsmongodbmongoose

Remove a particular object from array of DB in mongoose in Node.js


I want to delete a particular object from array in mongo DB using mongoose in node.js. In Doctor schema I have stored appointments in an array and at every index id of patient is stored so that we can find whose appointment has been booked. Also, at the time of booking we are pushing the doctor id, index of array in the 'bookingSlot' array of patient to finding his appointments. Now I have to implement delete appointment functionality.

Firstly, I'm finding the Doctor based on id and storing the appointment slot item (here-id of patient) in a variable for reference so that after deleting that slot we have reference to find patient using that patient id. Now, after deleting the appointment in doctor's schema, if we don't get error then we are finding the patient whose reference(id) we have stored above. Now our 'bookingSlot' array of patient contains several objects of appointments. But we want to remove a particular object whose id matched with doctor's id which we pass and index with the passed index. How can I achieve this?

This is schema of doctor

enter image description here

This is schema of patient

enter image description here

codes:-

exports.removeAppointment = (req, res) => {
  const { id, index, appointment } = req.body;
  var toBeDeletedAppointment;
  //this will contain id of patient for further reference to delete appointment in Patient model

  //get patient id before deleting the appointment slot
  Doctor.findById(id, (err, doctor) => {
    if (err) {
      return res.status(400).json({ error: "Error to find" });
    } else {
      toBeDeletedAppointment = doctor.appointment[index];
      // delete the slot by updating it with 0 (appointment's value will be passed 0 from frontend)
      Doctor.findByIdAndUpdate(
        { _id: id },
        { $set: { [`appointment.${index}`]: appointment } },
        { new: true, useFindAndModify: false },
        (err, doctor) => {
          if (err) {
            return res.status(400).json({ error: "Cannot Delete 103" });
          }
        },

        //once doctors slot is deleted now check patient's booking and remove appointment for that doctor

        Patient.findByIdAndUpdate(
          { _id: toBeDeletedAppointment },
          { $pull: { bookingDate: [{ id: id, index: index }] } },
          { safe: true, multi: false },
          (err, patient) => {
            if (err) {
              return res.status(400).json({
                message: err,
              });
            }
            res.json({
              message: "Deleted Successfully",
            });
          }
        )
      );
    }
  });
};

Thanks in advance :)

I have used put route coz I'm updating items of array in both schemas


Solution

  • $pull is what you need.

    The $pull operator removes from an existing array all instances of a value or values that match a specified condition.

    Example:

    Consider this stores collection:

        [
         {
           _id: 1,
           fruits: [ "apples", "pears", "oranges", "grapes", "bananas" ],
           vegetables: [ "carrots", "celery", "squash", "carrots" ]
         },
         {
           _id: 2,
           fruits: [ "plums", "kiwis", "oranges", "bananas", "apples" ],
           vegetables: [ "broccoli", "zucchini", "carrots", "onions" ]
         }
        ]
    

    The following operation removes

    • "apples" and "oranges" from the fruits array

    • "carrots" from the vegetables array

       db.stores.updateMany(
       { },
       { $pull: { fruits: { $in: [ "apples", "oranges" ] }, vegetables: "carrots" } })
      

    Confirm the result with db.collection.find():

        {
          _id: 1,
          fruits: [ 'pears', 'grapes', 'bananas' ],
          vegetables: [ 'celery', 'squash' ]
        },
        {
          _id: 2,
          fruits: [ 'plums', 'kiwis', 'bananas' ],
          vegetables: [ 'broccoli', 'zucchini', 'onions' ]
        }
    

    In your case, it will look something like this.

    Patient.findByIdAndUpdate(
              { _id: toBeDeletedAppointment },
              { $pull: { bookingDate: { id: id, index: index } } },
              { safe: true, multi: false },
              (err, patient) => {
                if (err) {
                  return res.status(400).json({
                    message: err,
                  });
                }
                res.json({
                  message: "Deleted Successfully",
                });
              }
            )
          );
    

    You can read more about $pull from here