Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

mongoose Soft delete using object ID

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.

like image 960
akash kariwal Avatar asked Aug 28 '26 20:08

akash kariwal


1 Answers

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

like image 118
Slava Borodulin Avatar answered Aug 30 '26 10:08

Slava Borodulin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!