Reputation: 3245
I'm using Mongoose in NestJs library and want to use mongoose-delete plugin for all of my schemas.
First i installed both mongoose-delete
and @Types/mongoose-delete
libraries but there is no typescript documentary for This plugin.
This is the recommended method for adding plugin by nest:
MongooseModule.forRoot(MONGO_URI, {
connectionFactory: connection => {
connection.plugin(require('mongoose-delete'));
return connection;
},
}),
And absolutely this generates esLint error:
Require statement not part of import statement.eslint
And I cannot use delete
function. It's not defined in the mongoose.Dcoument
export type ChannelDocument = Channel & Document;
constructor(
@InjectModel(Channel.name) private _channelModel: Model<ChannelDocument>,
) {}
async delete(id: string) {
this._channelModel.delete({ id });
// This is undefined -^
}
Upvotes: 2
Views: 5152
Reputation: 1
to use SoftDeleteModel
database migrate file
import mongoose, { Connection } from 'mongoose';
import { Cat, CatDocument, CatSchema } from './schema/cat.schema';
import { User, UserDocument, UserSchema } from './schema/user.schema';
import { Org, OrgDocument, OrgSchema } from './schema/org.schema';
import { NestFactory } from '@nestjs/core';
import { getConnectionToken } from '@nestjs/mongoose';
import { MongoModule } from './mongo.module';
import { Role, RoleDocument, RoleSchema } from './schema/role.schema';
import { SoftDeleteModel } from 'mongoose-delete';
const getModels = async () => {
mongoose.set('strictQuery', true);
const app = await NestFactory.create(MongoModule);
const connect = app.get<Connection>(getConnectionToken());
const catModel = connect.model(
Cat.name,
CatSchema,
) as unknown as SoftDeleteModel<CatDocument>;
const orgModel = connect.model(
Org.name,
OrgSchema,
) as unknown as SoftDeleteModel<OrgDocument>;
const userModel = connect.model(
User.name,
UserSchema,
) as unknown as SoftDeleteModel<UserDocument>;
const roleModel = connect.model(
Role.name,
RoleSchema,
) as unknown as SoftDeleteModel<RoleDocument>;
// Return models that will be used in migration methods
return {
connect,
catModel,
orgModel,
userModel,
roleModel,
};
};
export default getModels;
User Schema
import { Permission, Role } from './role.schema';
import { BaseOrgSchema } from './base-org.schema';
import { Org } from './org.schema';
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { HydratedDocument } from 'mongoose';
import mongoose from 'mongoose';
import { toJson } from '.';
@Schema({
toJSON: toJson,
timestamps: true,
})
export class User extends BaseOrgSchema {
/**
* name
*/
@Prop({ required: true })
// @Prop({ required: true, unique: true })
public name!: string;
/**
* password
*/
@Prop({ required: true, select: false })
public password!: string;
}
export const UserSchema = SchemaFactory.createForClass(User);
export type UserDocument = HydratedDocument<User>;
controller demo
import { SoftDeleteModel } from 'mongoose-delete';
export class UserController {
constructor(
@InjectModel(User.name)
private readonly model: SoftDeleteModel<UserDocument>,
) {}
@Delete(':id')
@Describe('delete user')
async delete(@Param('id') id: string): Promise<void> {
// no type error
const res = await this.model.delete(id);
if (res) {
return;
}
throw new BadRequestException('xxx');
}
}
db module demo
import { Global, Module } from '@nestjs/common';
import { MongoService } from './mongo.service';
import { MongooseModule } from '@nestjs/mongoose';
@Global()
@Module({
imports: [
MongooseModule.forRoot('mongodb://localhost/dbname', {
connectionFactory: (connection) => {
// eslint-disable-next-line @typescript-eslint/no-var-requires
connection.plugin(require('mongoose-delete'), {
deletedAt: true,
overrideMethods: true,
indexFields: true,
});
return connection;
},
lazyConnection: true,
}),
],
providers: [MongoService],
exports: [MongoService],
})
export class MongoModule {}
migrate demo
// Import your models here
import getModels from '@app/mongo/getModels';
export async function up(): Promise<void> {
const { userModel } = await getModels();
// if ignore type check run ok, miss type check
// no type error
await userModel.delete({});
}
export async function down(): Promise<void> {
// Write migration here
const { userModel } = await getModels();
// if ignore type check run ok, miss type check
// no type error
await userModel.restore({});
}
Upvotes: 0
Reputation: 11
use soft delete plugin => https://www.npmjs.com/package/soft-delete-mongoose-plugin
A simple and friendly soft delete plugin for Mongoose,implementation using TS. Methods were added and overridden on Mongoose model to realize soft deletion logic.
you can use it as a global plugin:
import { plugin } from 'mongoose';
import { SoftDelete } from 'soft-delete-mongoose-plugin';
// define soft delete field name
const IS_DELETED_FIELD = 'isDeleted';
const DELETED_AT_FIELD = 'deletedAt';
// Use soft delete plugin
plugin(
new SoftDelete({
isDeletedField: IS_DELETED_FIELD,
deletedAtField: DELETED_AT_FIELD,
}).getPlugin(),
);
// other code
// ...
Upvotes: 1
Reputation: 136
Try to restart you IDE (vscode if you use) after install this package: @types/mongoose-delete
Upvotes: 0
Reputation: 122
Please take a look at mongoose-softdelete-typescript.
import { Schema, model } from 'mongoose';
import { softDeletePlugin, ISoftDeletedModel, ISoftDeletedDocument } from 'mongoose-softdelete-typescript';
const TestSchema = new Schema({
name: { type: String, default: '' },
description: { type: String, default: 'description' },
});
TestSchema.plugin(softDeletePlugin);
const Test = model<ISoftDeletedDocument, ISoftDeletedModel<ISoftDeletedDocument>>('Test', TestSchema);
const test1 = new Test();
// delete single document
const newTest = await test1.softDelete();
// restore single document
const restoredTest = await test1.restore();
// find many deleted documents
const deletedTests = await Test.findDeleted(true);
// soft delete many documents with conditions
await Test.softDelete({ name: 'test' });
// support mongo transaction
const session = await Test.db.startSession();
session.startTransaction();
try {
const newTest = await test1.softDelete(session);
await session.commitTransaction();
} catch (e) {
console.log('e', e);
await session.abortTransaction();
} finally {
await session.endSession();
}
Upvotes: -1