Mongoose is a comprehensive MongoDB object modeling tool designed for asynchronous environments with schema-based validation, query building, and business logic hooks.
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Model class providing static methods for CRUD operations, queries, aggregation, and document management with full MongoDB feature support.
Define models from schemas and manage model registration.
/**
* Creates or retrieves a model
* @param name - Model name
* @param schema - Schema definition
* @param collection - Collection name (optional)
* @param options - Compilation options
* @returns Model constructor
*/
mongoose.model<T>(
name: string,
schema?: Schema<T>,
collection?: string,
options?: CompileModelOptions
): Model<T>;
/**
* Remove a model from Mongoose
* @param name - Model name to remove
* @returns Mongoose instance
*/
mongoose.deleteModel(name: string): typeof mongoose;
/**
* Get array of registered model names
* @returns Array of model names
*/
mongoose.modelNames(): string[];
interface CompileModelOptions {
/** Overwrite existing model */
overwriteModels?: boolean;
/** Connection to use */
connection?: Connection;
}Usage Examples:
const mongoose = require('mongoose');
// Define schema
const userSchema = new mongoose.Schema({
name: String,
email: String,
age: Number
});
// Create model
const User = mongoose.model('User', userSchema);
// Create model with custom collection name
const Admin = mongoose.model('Admin', userSchema, 'administrators');
// Check registered models
console.log(mongoose.modelNames()); // ['User', 'Admin']
// Remove model
mongoose.deleteModel('Admin');Create and insert new documents into the database.
interface Model<T> {
/**
* Create and save documents
* @param docs - Document data or array of document data
* @returns Promise resolving to created document(s)
*/
static create<T>(docs: T | T[]): Promise<T extends any[] ? T : T>;
/**
* Insert multiple documents
* @param docs - Array of document data
* @param options - Insert options
* @returns Promise resolving to inserted documents
*/
static insertMany<T>(
docs: T[],
options?: InsertManyOptions
): Promise<T[]>;
/**
* Create document instance without saving
* @param doc - Document data
* @returns New document instance
*/
constructor(doc?: Partial<T>): T;
}
interface InsertManyOptions {
/** Continue inserting on error */
ordered?: boolean;
/** Raw result instead of documents */
rawResult?: boolean;
/** Skip validation */
skipValidation?: boolean;
/** Lean mode */
lean?: boolean;
}Usage Examples:
// Create single document
const user = await User.create({
name: 'John Doe',
email: 'john@example.com',
age: 30
});
// Create multiple documents
const users = await User.create([
{ name: 'Alice', email: 'alice@example.com', age: 25 },
{ name: 'Bob', email: 'bob@example.com', age: 35 }
]);
// Insert many with options
const results = await User.insertMany(userData, {
ordered: false,
skipValidation: true
});
// Create instance without saving
const newUser = new User({ name: 'Jane' });
await newUser.save();Find and retrieve documents with flexible query conditions.
interface Model<T> {
/**
* Find multiple documents
* @param filter - Query conditions
* @param projection - Fields to include/exclude
* @returns Query instance
*/
static find<T>(
filter?: FilterQuery<T>,
projection?: ProjectionType<T>
): Query<T[], T>;
/**
* Find single document
* @param filter - Query conditions
* @param projection - Fields to include/exclude
* @returns Query instance
*/
static findOne<T>(
filter?: FilterQuery<T>,
projection?: ProjectionType<T>
): Query<T | null, T>;
/**
* Find document by ID
* @param id - Document ID
* @param projection - Fields to include/exclude
* @returns Query instance
*/
static findById<T>(
id: any,
projection?: ProjectionType<T>
): Query<T | null, T>;
/**
* Check if document exists
* @param filter - Query conditions
* @returns Promise resolving to document ID or null
*/
static exists<T>(filter: FilterQuery<T>): Promise<{ _id: any } | null>;
/**
* Count documents matching filter
* @param filter - Query conditions
* @returns Promise resolving to count
*/
static countDocuments<T>(filter?: FilterQuery<T>): Promise<number>;
/**
* Get estimated document count
* @param options - Count options
* @returns Promise resolving to estimated count
*/
static estimatedDocumentCount<T>(options?: any): Promise<number>;
/**
* Get distinct values for a field
* @param field - Field name
* @param filter - Query conditions
* @returns Promise resolving to distinct values array
*/
static distinct<T>(field: string, filter?: FilterQuery<T>): Promise<any[]>;
}Usage Examples:
// Find all users
const users = await User.find();
// Find with conditions
const adults = await User.find({ age: { $gte: 18 } });
// Find with projection
const userNames = await User.find({}, 'name email');
// Find one document
const user = await User.findOne({ email: 'john@example.com' });
// Find by ID
const user = await User.findById('507f1f77bcf86cd799439011');
// Check existence
const exists = await User.exists({ email: 'john@example.com' });
// Count documents
const count = await User.countDocuments({ age: { $gte: 18 } });
// Get distinct values
const ages = await User.distinct('age');Modify existing documents in the database.
interface Model<T> {
/**
* Update single document
* @param filter - Query conditions
* @param update - Update operations
* @param options - Update options
* @returns Promise resolving to update result
*/
static updateOne<T>(
filter: FilterQuery<T>,
update: UpdateQuery<T>,
options?: UpdateOptions
): Promise<UpdateResult>;
/**
* Update multiple documents
* @param filter - Query conditions
* @param update - Update operations
* @param options - Update options
* @returns Promise resolving to update result
*/
static updateMany<T>(
filter: FilterQuery<T>,
update: UpdateQuery<T>,
options?: UpdateOptions
): Promise<UpdateResult>;
/**
* Replace single document
* @param filter - Query conditions
* @param replacement - Replacement document
* @param options - Replace options
* @returns Promise resolving to update result
*/
static replaceOne<T>(
filter: FilterQuery<T>,
replacement: Partial<T>,
options?: ReplaceOptions
): Promise<UpdateResult>;
/**
* Find and update single document
* @param filter - Query conditions
* @param update - Update operations
* @param options - Update options
* @returns Promise resolving to updated document
*/
static findOneAndUpdate<T>(
filter: FilterQuery<T>,
update: UpdateQuery<T>,
options?: FindOneAndUpdateOptions
): Promise<T | null>;
/**
* Find by ID and update
* @param id - Document ID
* @param update - Update operations
* @param options - Update options
* @returns Promise resolving to updated document
*/
static findByIdAndUpdate<T>(
id: any,
update: UpdateQuery<T>,
options?: FindOneAndUpdateOptions
): Promise<T | null>;
}
interface UpdateOptions {
/** Create document if not found */
upsert?: boolean;
/** Return updated document */
new?: boolean;
/** Run validators on update */
runValidators?: boolean;
/** Set default values on upsert */
setDefaultsOnInsert?: boolean;
/** Fields to return */
select?: string | object;
/** Write concern */
writeConcern?: any;
/** Array filters for update */
arrayFilters?: any[];
}Usage Examples:
// Update single document
const result = await User.updateOne(
{ email: 'john@example.com' },
{ $set: { age: 31 } }
);
// Update multiple documents
await User.updateMany(
{ age: { $lt: 18 } },
{ $set: { status: 'minor' } }
);
// Find and update with return
const updatedUser = await User.findOneAndUpdate(
{ email: 'john@example.com' },
{ $inc: { loginCount: 1 } },
{ new: true } // Return updated document
);
// Update by ID
const user = await User.findByIdAndUpdate(
userId,
{ lastLogin: new Date() },
{ new: true }
);
// Upsert (update or insert)
const user = await User.findOneAndUpdate(
{ email: 'new@example.com' },
{ name: 'New User', age: 25 },
{ upsert: true, new: true }
);Remove documents from the database.
interface Model<T> {
/**
* Delete single document
* @param filter - Query conditions
* @param options - Delete options
* @returns Promise resolving to delete result
*/
static deleteOne<T>(
filter: FilterQuery<T>,
options?: DeleteOptions
): Promise<DeleteResult>;
/**
* Delete multiple documents
* @param filter - Query conditions
* @param options - Delete options
* @returns Promise resolving to delete result
*/
static deleteMany<T>(
filter: FilterQuery<T>,
options?: DeleteOptions
): Promise<DeleteResult>;
/**
* Find and delete single document
* @param filter - Query conditions
* @param options - Delete options
* @returns Promise resolving to deleted document
*/
static findOneAndDelete<T>(
filter: FilterQuery<T>,
options?: FindOneAndDeleteOptions
): Promise<T | null>;
/**
* Find by ID and delete
* @param id - Document ID
* @param options - Delete options
* @returns Promise resolving to deleted document
*/
static findByIdAndDelete<T>(
id: any,
options?: FindOneAndDeleteOptions
): Promise<T | null>;
/**
* Remove documents (deprecated, use deleteOne/deleteMany)
* @param filter - Query conditions
* @returns Promise resolving to delete result
*/
static remove<T>(filter: FilterQuery<T>): Promise<any>;
}
interface DeleteOptions {
/** Write concern */
writeConcern?: any;
/** Collation */
collation?: any;
}
interface FindOneAndDeleteOptions extends DeleteOptions {
/** Fields to return */
select?: string | object;
/** Sort order */
sort?: string | object;
/** Maximum time to wait */
maxTimeMS?: number;
}Usage Examples:
// Delete single document
const result = await User.deleteOne({ email: 'john@example.com' });
console.log(result.deletedCount); // 1
// Delete multiple documents
await User.deleteMany({ age: { $lt: 18 } });
// Find and delete with return
const deletedUser = await User.findOneAndDelete({
email: 'john@example.com'
});
// Delete by ID
const deletedUser = await User.findByIdAndDelete(userId);
// Check deletion result
if (result.deletedCount > 0) {
console.log('Document deleted successfully');
}Perform multiple operations in a single database round trip.
interface Model<T> {
/**
* Execute bulk write operations
* @param operations - Array of bulk operations
* @param options - Bulk options
* @returns Promise resolving to bulk result
*/
static bulkWrite<T>(
operations: BulkWriteOperation<T>[],
options?: BulkWriteOptions
): Promise<BulkWriteResult>;
/**
* Save multiple documents with validation
* @param documents - Array of documents to save
* @param options - Save options
* @returns Promise resolving to saved documents
*/
static bulkSave<T>(
documents: T[],
options?: BulkSaveOptions
): Promise<BulkSaveResult>;
}
type BulkWriteOperation<T> =
| { insertOne: { document: T } }
| { updateOne: { filter: FilterQuery<T>, update: UpdateQuery<T>, upsert?: boolean } }
| { updateMany: { filter: FilterQuery<T>, update: UpdateQuery<T>, upsert?: boolean } }
| { deleteOne: { filter: FilterQuery<T> } }
| { deleteMany: { filter: FilterQuery<T> } }
| { replaceOne: { filter: FilterQuery<T>, replacement: T, upsert?: boolean } };
interface BulkWriteOptions {
/** Execute operations in order */
ordered?: boolean;
/** Skip validation */
skipValidation?: boolean;
/** Include write concern */
writeConcern?: any;
}Usage Examples:
// Bulk write operations
const operations = [
{ insertOne: { document: { name: 'Alice', age: 25 } } },
{ updateOne: {
filter: { name: 'Bob' },
update: { $set: { age: 30 } }
}},
{ deleteOne: { filter: { name: 'Charlie' } } }
];
const result = await User.bulkWrite(operations);
console.log(result.insertedCount, result.modifiedCount, result.deletedCount);
// Bulk save documents
const users = [
new User({ name: 'Dave', age: 40 }),
new User({ name: 'Eve', age: 35 })
];
const saveResult = await User.bulkSave(users);Create and execute aggregation pipelines for complex data processing.
interface Model<T> {
/**
* Create aggregation pipeline
* @param pipeline - Aggregation stages
* @param options - Aggregation options
* @returns Aggregate instance
*/
static aggregate<T>(
pipeline?: PipelineStage[],
options?: AggregateOptions
): Aggregate<T[]>;
}Usage Examples:
// Basic aggregation
const results = await User.aggregate([
{ $match: { age: { $gte: 18 } } },
{ $group: { _id: '$status', count: { $sum: 1 } } },
{ $sort: { count: -1 } }
]);
// Complex aggregation with lookup
const userPosts = await User.aggregate([
{ $match: { status: 'active' } },
{ $lookup: {
from: 'posts',
localField: '_id',
foreignField: 'author',
as: 'posts'
}},
{ $addFields: { postCount: { $size: '$posts' } } },
{ $sort: { postCount: -1 } }
]);Manage database indexes for query optimization.
interface Model<T> {
/**
* Create indexes defined in schema
* @param options - Index creation options
* @returns Promise resolving when indexes are created
*/
static createIndexes<T>(options?: any): Promise<void>;
/**
* Synchronize indexes with schema
* @param options - Sync options
* @returns Promise resolving to sync result
*/
static syncIndexes<T>(options?: any): Promise<string[]>;
/**
* List all indexes on collection
* @returns Promise resolving to index array
*/
static listIndexes<T>(): Promise<any[]>;
/**
* Ensure index exists
* @param fieldOrSpec - Index specification
* @param options - Index options
* @returns Promise resolving to index name
*/
static ensureIndexes<T>(options?: any): Promise<void>;
}Usage Examples:
// Create all schema-defined indexes
await User.createIndexes();
// Sync indexes (remove unused, add missing)
const result = await User.syncIndexes();
console.log('Synced indexes:', result);
// List existing indexes
const indexes = await User.listIndexes();
console.log('Current indexes:', indexes);Advanced model operations for index management, collection operations, and database administration.
interface Model<T> {
/**
* Create aggregation pipeline
* @param pipeline - Array of aggregation stages
* @returns Aggregate instance
*/
static aggregate<ResultType>(pipeline?: PipelineStage[]): Aggregate<ResultType[]>;
/**
* Explicitly create collection in database
* @param options - Collection creation options
* @returns Promise resolving to native collection
*/
static createCollection(options?: CreateCollectionOptions): Promise<mongodb.Collection>;
/**
* Create all schema indexes
* @param options - Index creation options
* @returns Promise that resolves when indexes are created
*/
static createIndexes(options?: any): Promise<void>;
/**
* Compare schema indexes with database indexes
* @returns Promise with index differences
*/
static diffIndexes(): Promise<IndexesDiff>;
/**
* Deprecated alias for createIndexes
* @returns Promise that resolves when indexes are created
*/
static ensureIndexes(): Promise<void>;
/**
* Create document from plain object without validation
* @param obj - Plain object to hydrate
* @param projection - Field projection
* @returns Hydrated document instance
*/
static hydrate(obj: any, projection?: any): HydratedDocument<T>;
/**
* Initialize model (create collection and indexes)
* @returns Promise resolving to model
*/
static init(): Promise<Model<T>>;
/**
* List all indexes for this model's collection
* @returns Promise with array of index definitions
*/
static listIndexes(): Promise<IndexDefinition[]>;
/**
* Start database session for transactions
* @param options - Session options
* @returns Promise with client session
*/
static startSession(options?: ClientSessionOptions): Promise<ClientSession>;
/**
* Synchronize schema indexes with database
* @param options - Sync options
* @returns Promise with array of synced index names
*/
static syncIndexes(options?: SyncIndexesOptions): Promise<string[]>;
/**
* Translate field aliases in query object
* @param raw - Raw query object
* @returns Query object with translated aliases
*/
static translateAliases(raw: any): any;
/**
* Validate object against schema without creating document
* @param obj - Object to validate
* @param pathsToValidate - Specific paths to validate
* @returns Promise that resolves if valid, rejects if invalid
*/
static validate(obj: any, pathsToValidate?: string[]): Promise<void>;
/**
* Create change stream on collection
* @param pipeline - Aggregation pipeline for filtering changes
* @param options - Change stream options
* @returns Change stream cursor
*/
static watch(pipeline?: any[], options?: ChangeStreamOptions): ChangeStream;
}interface UpdateResult {
/** Operation was accepted */
acknowledged: boolean;
/** Number of documents matched */
matchedCount: number;
/** Number of documents modified */
modifiedCount: number;
/** ID of upserted document */
upsertedId?: ObjectId;
/** Number of documents upserted */
upsertedCount: number;
}
interface DeleteResult {
/** Operation was accepted */
acknowledged: boolean;
/** Number of documents deleted */
deletedCount: number;
}
interface BulkWriteResult {
/** Operation was accepted */
acknowledged: boolean;
/** Number of documents inserted */
insertedCount: number;
/** IDs of inserted documents */
insertedIds: { [index: number]: ObjectId };
/** Number of documents matched */
matchedCount: number;
/** Number of documents modified */
modifiedCount: number;
/** Number of documents deleted */
deletedCount: number;
/** Number of documents upserted */
upsertedCount: number;
/** IDs of upserted documents */
upsertedIds: { [index: number]: ObjectId };
}
type FilterQuery<T> = {
[P in keyof T]?: T[P] | QuerySelector<T[P]>;
} & QuerySelector<T>;
interface QuerySelector<T> {
$eq?: T;
$ne?: T;
$gt?: T;
$gte?: T;
$lt?: T;
$lte?: T;
$in?: T[];
$nin?: T[];
$exists?: boolean;
$regex?: RegExp | string;
$options?: string;
$all?: T[];
$size?: number;
$elemMatch?: any;
$not?: QuerySelector<T>;
$and?: FilterQuery<T>[];
$or?: FilterQuery<T>[];
$nor?: FilterQuery<T>[];
$where?: string | Function;
$expr?: any;
$jsonSchema?: any;
$mod?: [number, number];
$text?: {
$search: string;
$language?: string;
$caseSensitive?: boolean;
$diacriticSensitive?: boolean;
};
$near?: any;
$nearSphere?: any;
$geoIntersects?: any;
$geoWithin?: any;
$within?: any;
$centerSphere?: any;
}
type UpdateQuery<T> = {
$set?: Partial<T>;
$unset?: { [K in keyof T]?: '' | 1 | true };
$inc?: Partial<T>;
$mul?: Partial<T>;
$min?: Partial<T>;
$max?: Partial<T>;
$push?: any;
$pushAll?: any;
$addToSet?: any;
$pop?: any;
$pull?: any;
$pullAll?: any;
$rename?: { [key: string]: string };
$bit?: any;
$currentDate?: any;
} & Partial<T>;
type ProjectionType<T> = string | { [K in keyof T]?: 1 | 0 | boolean } | { [key: string]: 1 | 0 | boolean };
interface CreateCollectionOptions {
/** Capped collection options */
capped?: boolean;
/** Maximum collection size */
size?: number;
/** Maximum document count */
max?: number;
/** Validation rules */
validator?: any;
/** Validation level */
validationLevel?: 'off' | 'strict' | 'moderate';
/** Validation action */
validationAction?: 'error' | 'warn';
}
interface IndexesDiff {
/** Indexes to create */
toDrop: IndexDefinition[];
/** Indexes to drop */
toCreate: IndexDefinition[];
}
interface IndexDefinition {
/** Index specification */
key: any;
/** Index name */
name?: string;
/** Index options */
[option: string]: any;
}
interface SyncIndexesOptions {
/** Continue on index creation error */
continueOnError?: boolean;
/** Drop indexes not in schema */
dropIndexes?: boolean;
}
interface HydratedDocument<T> extends Document {
/** Document data */
[K in keyof T]: T[K];
}
interface ClientSessionOptions {
/** Causally consistent reads */
causalConsistency?: boolean;
/** Default transaction options */
defaultTransactionOptions?: TransactionOptions;
}
interface TransactionOptions {
/** Read concern */
readConcern?: ReadConcern;
/** Write concern */
writeConcern?: WriteConcern;
/** Read preference */
readPreference?: ReadPreference;
/** Max commit time */
maxCommitTimeMS?: number;
}
interface ChangeStreamOptions {
/** Full document option */
fullDocument?: 'default' | 'updateLookup';
/** Full document before change */
fullDocumentBeforeChange?: 'off' | 'whenAvailable' | 'required';
/** Resume token */
resumeAfter?: any;
/** Start after token */
startAfter?: any;
/** Start at operation time */
startAtOperationTime?: any;
/** Max await time */
maxAwaitTimeMS?: number;
/** Batch size */
batchSize?: number;
/** Collation */
collation?: any;
}
interface ChangeStream {
/** Stream next change */
next(): Promise<ChangeStreamDocument>;
/** Close stream */
close(): Promise<void>;
/** Check if stream is closed */
isClosed(): boolean;
/** Resume token */
resumeToken: any;
}
interface ChangeStreamDocument {
/** Operation type */
operationType: 'insert' | 'update' | 'replace' | 'delete' | 'invalidate' | 'drop' | 'dropDatabase' | 'rename';
/** Full document */
fullDocument?: any;
/** Document key */
documentKey?: any;
/** Update description */
updateDescription?: {
updatedFields?: any;
removedFields?: string[];
};
/** Resume token */
_id: any;
/** Namespace */
ns: {
db: string;
coll: string;
};
/** Cluster time */
clusterTime: any;
}