Jakub
Jakub

Reputation: 2729

How to delete the referenced document in one collection and its record from the referred other collection

In my NodeJS API and MongoDB, I'm trying to delete a record which is a reference to another collection. What I would like to do is to delete the referred objectId and the records related to the other collection which is referred.

I have 2 models Profiles and Posts and I want to delete the same one post from Profile and Post collection. I was able to delete the reference id in Profile but I don't know how to delete also the record from Posts collection.

I tried this:

async delete(req, res) {
        try {
            // Match with username and pull to remove
            await Profile.findOneAndUpdate(
                { _id: res.id._id },
                { $pull: { posts: req.params.postId } },
                err => {
                    if (err) {
                        throw new ErrorHandlers.ErrorHandler(500, err);
                    }
                    res.json({ Message: "Deleted" });
                }
            );
        } catch (error) {
            res.status(500).send(error);
        }
    } 

And my 2 models:

// Here defining profile model
// Embedded we have the Experience as []
const { Connect } = require("../db");
const { isEmail } = require("validator");

const postSchema = {
    type: Connect.Schema.Types.ObjectId,
    ref: "Post"
};

const experienceSchema = {
    role: {
        type: String,
        required: true
    },
    company: {
        type: String,
        required: true
    },
    startDate: {
        type: Date,
        required: true
    },
    endDate: {
        type: Date,
        required: false
    },
    description: {
        type: String,
        required: false
    },

    area: {
        type: String,
        required: true
    },
    createdAt: {
        type: Date,
        default: Date.now,
        required: false
    },

    updatedAt: {
        type: Date,
        default: Date.now,
        required: false
    },

    username: {
        type: String,
        required: false
    },
    image: {
        type: String,
        required: false,
        default: "https://via.placeholder.com/150"
    }
};

const profileSchema = {
    firstname: {
        type: String,
        required: true
    },

    surname: {
        type: String,
        required: true
    },

    email: {
        type: String,
        trim: true,
        lowercase: true,
        unique: true,
        required: [true, "Email is required"],
        validate: {
            validator: string => isEmail(string),
            message: "Provided email is invalid"
        }
    },

    bio: {
        type: String,
        required: true
    },

    title: {
        type: String,
        required: true
    },

    area: {
        type: String,
        required: true
    },

    imageUrl: {
        type: String,
        required: false,
        default: "https://via.placeholder.com/150"
    },

    username: {
        type: String,
        required: true,
        unique: true
    },

    experience: [experienceSchema],
    posts: [postSchema],

    createdAt: {
        type: Date,
        default: Date.now,
        required: false
    },

    updatedAt: {
        type: Date,
        default: Date.now,
        required: false
    }
};



const collectionName = "profile";
const profileSchemaModel = Connect.Schema(profileSchema);
const Profile = Connect.model(collectionName, profileSchemaModel);

module.exports = Profile;

const { Connect } = require("../db");

const reactionSchema = {
    likedBy: {
        type: String,
        unique: true,
        sparse: true
    }
};

const postSchema = {
    text: {
        type: String,
        required: true,
        unique: true,
        sparse: false
    },

    profile: {
        type: Connect.Schema.Types.ObjectId,
        ref: "Profile",
    },

    image: {
        type: String,
        default: "https://via.placeholder.com/150",
        required: false
    },
    createdAt: {
        type: Date,
        default: Date.now,
        required: false
    },

    updatedAt: {
        type: Date,
        default: Date.now,
        required: false
    },

    reactions: [reactionSchema],

    comments: {
        type: Connect.Schema.Types.ObjectId,
        ref: "Comment",
        required: false
    }
};

const collectionName = "post";
const postSchemaModel = Connect.Schema(postSchema);
const Post = Connect.model(collectionName, postSchemaModel);

module.exports = Post;

Upvotes: 1

Views: 531

Answers (1)

Tunmise Ogunniyi
Tunmise Ogunniyi

Reputation: 2573

Just add a query to remove the post after pulling it's ID from the profile collection:

async delete(req, res) {
  try {
      // Match with username and pull to remove
      await Profile.findOneAndUpdate(
          { _id: res.id._id },
          { $pull: { posts: req.params.postId } },
          // You don't need an error callback here since you are 
          // using async/await. Handle the error in the catch block.
      );
      await Posts.remove({ _id: req.params.postId });
  } catch (error) {
      // This is where you handle the error
      res.status(500).send(error);
  }
} 

Upvotes: 2

Related Questions