6

So I am trying to use mongoose-delete plugin to soft delete data in mongoDB, but the request has only got the object ID for the mongoose object. So in order to "soft-delete" the data, I am having to first do a findOne, and then use the delete function on it. Is there any plugin or function which can let me soft-delete this data using only the object ID? instead of using two hits to the DB. The data is critical, hence only need a soft delete option, and not a hard delete. And I cannot use the common update function, need some plugin, or node module to do this for me.

akash kariwal
  • 81
  • 1
  • 1
  • 6

4 Answers4

17

you don't need any libraries, it's easy to write yourself using middleware and $isDeleted document method

example plugin code:

import mongoose from 'mongoose';

export type TWithSoftDeleted = {
  isDeleted: boolean;
  deletedAt: Date | null;
}

type TDocument = TWithSoftDeleted & mongoose.Document;

const softDeletePlugin = (schema: mongoose.Schema) => {
  schema.add({
    isDeleted: {
      type: Boolean,
      required: true,
      default: false,
    },
    deletedAt: {
      type: Date,
      default: null,
    },
  });

  const typesFindQueryMiddleware = [
    'count',
    'find',
    'findOne',
    'findOneAndDelete',
    'findOneAndRemove',
    'findOneAndUpdate',
    'update',
    'updateOne',
    'updateMany',
  ];

  const setDocumentIsDeleted = async (doc: TDocument) => {
    doc.isDeleted = true;
    doc.deletedAt = new Date();
    doc.$isDeleted(true);
    await doc.save();
  };

  const excludeInFindQueriesIsDeleted = async function (
    this: mongoose.Query<TDocument>,
    next: mongoose.HookNextFunction
  ) {
    this.where({ isDeleted: false });
    next();
  };

  const excludeInDeletedInAggregateMiddleware = async function (
    this: mongoose.Aggregate<any>,
    next: mongoose.HookNextFunction
  ) {
    this.pipeline().unshift({ $match: { isDeleted: false } });
    next();
  };

  schema.pre('remove', async function (
    this: TDocument,
    next: mongoose.HookNextFunction
  ) {
    await setDocumentIsDeleted(this);
    next();
  });

  typesFindQueryMiddleware.forEach((type) => {
    schema.pre(type, excludeInFindQueriesIsDeleted);
  });

  schema.pre('aggregate', excludeInDeletedInAggregateMiddleware);
};

export {
  softDeletePlugin,
};

you can use it as a global plugin or as a plugin for speciffed schema

2

You can use mongoose-delete: https://github.com/dsanel/mongoose-delete.

It provides new delete function.

0

You can use Mongoosejs Soft delete. Look at the code at GitHub Repository.

Parth Patel
  • 3,937
  • 2
  • 27
  • 44
0

I know it's a bit late. But, I hope this can help someone out there

Here's an npm package that's compatible with JS & TS for soft deleting elements and restoring them using mongoose

https://www.npmjs.com/package/soft-delete-plugin-mongoose