NestJS module that provides seamless integration between NestJS and Mongoose ODM for MongoDB database operations
80
Pending
Does it follow best practices?
Impact
80%
1.02xAverage score across 10 eval scenarios
Pending
The risk profile of this skill
Decorators for injecting Mongoose models and connections into NestJS services and controllers. The dependency injection system integrates seamlessly with NestJS's DI container to provide type-safe model and connection injection.
Injects a Mongoose model into constructor parameters for use in services and controllers.
/**
* Parameter decorator that injects a Mongoose model
* @param model - Model name to inject
* @param connectionName - Optional connection name for multi-database setup
* @returns Parameter decorator function
*/
function InjectModel(model: string, connectionName?: string): ParameterDecorator;Usage Examples:
import { Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';
import { User } from './schemas/user.schema';
// Basic model injection
@Injectable()
export class UserService {
constructor(@InjectModel(User.name) private userModel: Model<User>) {}
async create(createUserDto: any): Promise<User> {
const createdUser = new this.userModel(createUserDto);
return createdUser.save();
}
async findAll(): Promise<User[]> {
return this.userModel.find().exec();
}
async findById(id: string): Promise<User> {
return this.userModel.findById(id).exec();
}
async update(id: string, updateUserDto: any): Promise<User> {
return this.userModel.findByIdAndUpdate(id, updateUserDto, { new: true }).exec();
}
async delete(id: string): Promise<User> {
return this.userModel.findByIdAndDelete(id).exec();
}
}
// Multi-database model injection
@Injectable()
export class UserService {
constructor(
@InjectModel(User.name, 'users-db') private userModel: Model<User>,
@InjectModel(Profile.name, 'profiles-db') private profileModel: Model<Profile>,
) {}
async createUserWithProfile(userData: any, profileData: any): Promise<{ user: User; profile: Profile }> {
const user = await new this.userModel(userData).save();
const profile = await new this.profileModel({ ...profileData, userId: user._id }).save();
return { user, profile };
}
}
// Multiple models in single service
@Injectable()
export class BlogService {
constructor(
@InjectModel(Post.name) private postModel: Model<Post>,
@InjectModel(Comment.name) private commentModel: Model<Comment>,
@InjectModel(User.name) private userModel: Model<User>,
) {}
async createPostWithAuthor(postData: any, authorId: string): Promise<Post> {
const author = await this.userModel.findById(authorId);
if (!author) {
throw new Error('Author not found');
}
const post = new this.postModel({ ...postData, author: authorId });
return post.save();
}
async addComment(postId: string, commentData: any): Promise<Comment> {
const post = await this.postModel.findById(postId);
if (!post) {
throw new Error('Post not found');
}
const comment = new this.commentModel({ ...commentData, post: postId });
return comment.save();
}
}Injects a Mongoose connection instance for advanced database operations and transaction management.
/**
* Parameter decorator that injects a Mongoose connection
* @param name - Optional connection name for multi-database setup
* @returns Parameter decorator function
*/
function InjectConnection(name?: string): ParameterDecorator;Usage Examples:
import { Injectable } from '@nestjs/common';
import { InjectConnection, InjectModel } from '@nestjs/mongoose';
import { Connection, Model } from 'mongoose';
import { User } from './schemas/user.schema';
import { Order } from './schemas/order.schema';
// Basic connection injection
@Injectable()
export class DatabaseService {
constructor(@InjectConnection() private connection: Connection) {}
async getDatabaseStats(): Promise<any> {
const stats = await this.connection.db.stats();
return {
database: this.connection.name,
collections: stats.collections,
dataSize: stats.dataSize,
indexSize: stats.indexSize,
};
}
async createIndexes(): Promise<void> {
const collections = await this.connection.db.listCollections().toArray();
for (const collection of collections) {
await this.connection.collection(collection.name).createIndex({ createdAt: -1 });
}
}
}
// Named connection injection
@Injectable()
export class MultiDbService {
constructor(
@InjectConnection('users-db') private usersConnection: Connection,
@InjectConnection('orders-db') private ordersConnection: Connection,
) {}
async syncUserData(userId: string): Promise<void> {
const session = await this.usersConnection.startSession();
try {
await session.withTransaction(async () => {
// Perform operations within transaction
const user = await this.usersConnection.collection('users').findOne({ _id: userId });
if (user) {
await this.usersConnection.collection('user_cache').replaceOne(
{ userId },
{ ...user, lastSync: new Date() },
{ upsert: true }
);
}
});
} finally {
await session.endSession();
}
}
}
// Transaction management with connection and models
@Injectable()
export class TransactionService {
constructor(
@InjectConnection() private connection: Connection,
@InjectModel(User.name) private userModel: Model<User>,
@InjectModel(Order.name) private orderModel: Model<Order>,
) {}
async createUserAndOrder(userData: any, orderData: any): Promise<{ user: User; order: Order }> {
const session = await this.connection.startSession();
try {
const result = await session.withTransaction(async () => {
// Create user within transaction
const user = new this.userModel(userData);
await user.save({ session });
// Create order within same transaction
const order = new this.orderModel({ ...orderData, userId: user._id });
await order.save({ session });
return { user, order };
});
return result;
} finally {
await session.endSession();
}
}
}Generates the dependency injection token used for model injection.
/**
* Generates dependency injection token for a model
* @param model - Model name
* @param connectionName - Optional connection name
* @returns DI token string
*/
function getModelToken(model: string, connectionName?: string): string;Usage Examples:
import { getModelToken } from '@nestjs/mongoose';
// Get token for default connection
const userToken = getModelToken('User');
// Returns: 'UserModel'
// Get token for named connection
const userTokenWithConnection = getModelToken('User', 'users-db');
// Returns: 'users-db/UserModel'
// Use in custom providers
const providers = [
{
provide: 'CUSTOM_USER_SERVICE',
useFactory: (userModel: Model<User>) => {
return new CustomUserService(userModel);
},
inject: [getModelToken(User.name)],
},
];Generates the dependency injection token used for connection injection.
/**
* Generates dependency injection token for a connection
* @param name - Optional connection name
* @returns DI token string
*/
function getConnectionToken(name?: string): string;Usage Examples:
import { getConnectionToken } from '@nestjs/mongoose';
// Get token for default connection
const defaultConnectionToken = getConnectionToken();
// Returns: 'DatabaseConnection'
// Get token for named connection
const namedConnectionToken = getConnectionToken('users-db');
// Returns: 'users-db'
// Use in custom providers
const providers = [
{
provide: 'DATABASE_HEALTH_CHECK',
useFactory: (connection: Connection) => {
return new DatabaseHealthCheck(connection);
},
inject: [getConnectionToken()],
},
];import { Module, Provider } from '@nestjs/common';
import { getModelToken, getConnectionToken } from '@nestjs/mongoose';
const customProviders: Provider[] = [
{
provide: 'USER_REPOSITORY',
useFactory: (userModel: Model<User>) => {
return new UserRepository(userModel);
},
inject: [getModelToken(User.name)],
},
{
provide: 'DATABASE_MANAGER',
useFactory: (connection: Connection) => {
return new DatabaseManager(connection);
},
inject: [getConnectionToken()],
},
];
@Module({
providers: [...customProviders],
exports: ['USER_REPOSITORY', 'DATABASE_MANAGER'],
})
export class CustomModule {}import { Test, TestingModule } from '@nestjs/testing';
import { getModelToken } from '@nestjs/mongoose';
describe('UserService', () => {
let service: UserService;
let model: Model<User>;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
UserService,
{
provide: getModelToken(User.name),
useValue: {
find: jest.fn(),
findById: jest.fn(),
create: jest.fn(),
save: jest.fn(),
},
},
],
}).compile();
service = module.get<UserService>(UserService);
model = module.get<Model<User>>(getModelToken(User.name));
});
it('should find all users', async () => {
const users = [{ name: 'Test User' }];
jest.spyOn(model, 'find').mockReturnValue({
exec: jest.fn().mockResolvedValue(users),
} as any);
const result = await service.findAll();
expect(result).toEqual(users);
});
});docs
evals
scenario-1
scenario-2
scenario-3
scenario-4
scenario-5
scenario-6
scenario-7
scenario-8
scenario-9
scenario-10