From api-database-mongodb
MongoDB with Mongoose ODM - schemas, models, queries, aggregation, indexes, TypeScript typing, connection management
How this skill is triggered — by the user, by Claude, or both
Slash command
/api-database-mongodb:api-database-mongodbThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
> **Quick Guide:** Use Mongoose as the ODM for MongoDB. Define schemas with automatic TypeScript inference, use `lean()` for read-only queries, prefer embedding over referencing for co-accessed data, place `$match` early in aggregation pipelines, and always define indexes to match your query patterns.
Quick Guide: Use Mongoose as the ODM for MongoDB. Define schemas with automatic TypeScript inference, use
lean()for read-only queries, prefer embedding over referencing for co-accessed data, place$matchearly in aggregation pipelines, and always define indexes to match your query patterns.
<critical_requirements>
All code must follow project conventions in CLAUDE.md (kebab-case, named exports, import ordering,
import type, named constants)
(You MUST define Mongoose middleware (pre/post hooks) BEFORE calling model() -- hooks registered after model compilation are silently ignored)
(You MUST pass { session } to EVERY operation inside a transaction -- missing session causes operations to run outside the transaction)
(You MUST use .lean() for read-only queries that send results directly to API responses -- skipping lean wastes 3x memory on hydration overhead)
(You MUST use 127.0.0.1 instead of localhost in connection strings -- Node.js 18+ prefers IPv6 and localhost can cause connection timeouts)
(You MUST NOT use findOneAndUpdate / updateOne and expect save middleware to fire -- only save() and create() trigger document middleware)
</critical_requirements>
Auto-detection: MongoDB, Mongoose, mongoose.connect, Schema, model, ObjectId, populate, aggregate, $match, $group, $lookup, lean, HydratedDocument, InferSchemaType, MongoClient, Atlas
When to use:
Key patterns covered:
When NOT to use:
Detailed Resources:
Core Patterns:
Query Patterns:
Aggregation:
Advanced Patterns:
Indexing:
MongoDB is a document database. Mongoose provides schema-based modeling on top of it. The core principle: data that is accessed together should be stored together.
Core principles:
.lean() for read-only queries. It returns plain objects (3x less memory) instead of full Mongoose documents.When to use MongoDB / Mongoose:
Establish a single connection at startup with named constants for pool/timeout config and environment variables for credentials. See examples/core.md for full examples including connection events and graceful shutdown.
const connection = await mongoose.connect(process.env.MONGODB_URI!, {
maxPoolSize: POOL_SIZE_MAX,
minPoolSize: POOL_SIZE_MIN,
serverSelectionTimeoutMS: SERVER_SELECTION_TIMEOUT_MS,
socketTimeoutMS: SOCKET_TIMEOUT_MS,
retryWrites: true,
retryReads: true,
});
Let Mongoose infer types from the schema definition. Use explicit interfaces only when adding methods, statics, or virtuals. See examples/core.md for full typing examples with HydratedDocument, InferSchemaType, and generic parameters.
// Preferred: automatic type inference
const userSchema = new Schema(
{
name: { type: String, required: true, trim: true },
email: { type: String, required: true, unique: true, lowercase: true },
role: {
type: String,
enum: ["admin", "user", "moderator"] as const,
default: "user",
},
},
{ timestamps: true },
);
const User = model("User", userSchema);
// For methods/statics/virtuals: explicit interfaces with Schema generics
const userSchema = new Schema<IUser, UserModel, IUserMethods, {}, IUserVirtuals>({ ... });
Use .lean() for read-only queries, save() when middleware must fire, findByIdAndUpdate with { runValidators: true } for direct updates. See examples/core.md for full CRUD examples.
const user = await User.findById(id).lean(); // read-only, 3x less memory
await User.insertMany(users, { ordered: false }); // bulk insert
await User.findByIdAndUpdate(id, update, { new: true, runValidators: true }); // direct update
Use comparison/logical operators for filters, .populate() with field selection and limits. See examples/queries.md for dynamic query builders, cursor-based pagination, and populate patterns.
const post = await Post.findById(id)
.populate("author", "name email")
.populate({
path: "comments",
options: { sort: { createdAt: -1 }, limit: 10 },
})
.lean();
Add custom error messages, regex validation, and array-level validators. See examples/core.md for complete validation examples.
price: {
type: Number,
required: true,
min: [0, "Price cannot be negative"],
validate: { validator: (v: number) => Number.isFinite(v), message: "Price must be finite" },
},
sku: {
type: String,
required: true,
unique: true,
match: [/^[A-Z]{2}-\d{6}$/, "SKU must match format XX-000000"],
},
<red_flags>
High Priority Issues:
.lean() and expecting .save() to work -- lean returns plain objects without Mongoose methodsmodel() call -- hooks are silently ignoredPromise.all()) -- MongoDB does not support parallel operations within a single transactionlocalhost in connection strings on Node.js 18+ -- IPv6 preference causes connection timeouts, use 127.0.0.1{ session } on any operation inside a transaction -- that operation runs outside the transactionMedium Priority Issues:
findOneAndUpdate / updateOne and expecting pre('save') hooks to fire -- only save() and create() trigger document middleware.populate() without limit or field selection -- can return thousands of documents per queryrunValidators: true on findOneAndUpdate -- schema validation is skipped by default on updates$where or JavaScript expressions in queries -- disables indexes and enables injectionCommon Mistakes:
{ new: true } on findOneAndUpdate -- returns the old document by defaultSchema.Types.ObjectId in TypeScript interfaces instead of Types.ObjectId -- Schema.Types.ObjectId is for schema definitions, Types.ObjectId is for interfaces.lean() on write operations -- lean is for reads onlydoc.isNew in post('save') hooks -- always false after save, use this.$locals.wasNew set in a pre('save') hookGotchas & Edge Cases:
deleteOne / deleteMany do not trigger pre('remove') middleware -- use findOneAndDelete or document .deleteOne() if you need middlewaretoJSON() / toObject() by default -- set { toJSON: { virtuals: true } } in schema optionsremove() was completely removed in Mongoose 7+ -- use deleteOne() or deleteMany() insteadnext() in pre hooks -- use async/await insteadFilterQuery to QueryFilter -- update TypeScript imports if upgradingupdatePipeline: true for pipeline-style updates -- they throw by defaultbackground index option -- MongoDB 4.2+ builds all indexes in the background by default</red_flags>
<critical_reminders>
All code must follow project conventions in CLAUDE.md (kebab-case, named exports, import ordering,
import type, named constants)
(You MUST define Mongoose middleware (pre/post hooks) BEFORE calling model() -- hooks registered after model compilation are silently ignored)
(You MUST pass { session } to EVERY operation inside a transaction -- missing session causes operations to run outside the transaction)
(You MUST use .lean() for read-only queries that send results directly to API responses -- skipping lean wastes 3x memory on hydration overhead)
(You MUST use 127.0.0.1 instead of localhost in connection strings -- Node.js 18+ prefers IPv6 and localhost can cause connection timeouts)
(You MUST NOT use findOneAndUpdate / updateOne and expect save middleware to fire -- only save() and create() trigger document middleware)
Failure to follow these rules will cause silent data corruption, middleware bypass, or transaction isolation failures.
</critical_reminders>
Searches MemPalace before answering questions about past work, people, projects, or prior decisions. Returns verbatim stored content instead of guessing from model memory.
Guides Payload CMS config (payload.config.ts), collections, fields, hooks, access control, APIs. Debugs validation errors, security, relationships, queries, transactions, hook behavior.
Implements vector databases with Pinecone, Weaviate, Qdrant, Milvus, pgvector for semantic search, RAG, recommendations, and similarity systems. Optimizes embeddings, indexing, and hybrid search.
npx claudepluginhub agents-inc/skills --plugin api-database-mongodb