MongoDB
Document-oriented NoSQL database - flexible schemas, horizontal scaling, and rich aggregation pipeline make it ideal for hierarchical or rapidly evolving data models.
skill: MongoDB category: Backend tags: [MongoDB, NoSQL, Mongoose, Aggregation, Atlas] readingTime: 6
MongoDB is ideal for hierarchical data (nested documents), rapidly changing schemas, and horizontal scaling. For relational data with strong consistency requirements, use PostgreSQL. For time-series data, use InfluxDB or TimescaleDB. Don't default to MongoDB just because it's 'easier' - schema discipline matters.
Workflow
- Connect and model with MongooseMongoose adds schemas, validation, and middleware on top of the MongoDB driver - essential for enforcing data consistency in a schemaless DB.
- CRUD operationsMongoDB's query language is JSON-based - intuitive for JavaScript developers and powerful for nested document queries.
- Use the aggregation pipelineThe aggregation pipeline is MongoDB's SQL GROUP BY + JOIN - transform, group, and analyze documents in one query.
- Index strategicallyMongoDB queries without an index do a full collection scan - fine for small collections, catastrophic at scale.
- Use Atlas Search for full-text searchAtlas Search (Lucene-based) handles fuzzy matching, typo tolerance, synonyms, and relevance ranking - far beyond MongoDB's native text indexes.
Output Format
MongoDB data layer with Mongoose schemas, indexed queries, and aggregation pipelines.
models/
├── User.ts # Schema + indexes + methods
├── Post.ts
└── Order.ts
repositories/
├── userRepo.ts # CRUD + aggregation queries
└── orderRepo.tsExamples
Input
Output
Edge Cases & Gotchas
- ObjectId vs. string IDs - MongoDB uses ObjectId for _id by default. When querying by _id, pass new mongoose.Types.ObjectId(id) - passing a raw string won't match.
- Mongoose validation on update - Model.updateOne() bypasses Mongoose validators by default. Use { runValidators: true } in options.
- Connection pool exhaustion - Too many concurrent operations exhaust the connection pool. Set maxPoolSize=50 (default 5) and add connection monitoring.
- Array mutation operators - Replacing an array with $set replaces the entire array. Use $push, $pull, $addToSet for mutations that preserve other elements.
When to Break These Rules
- Use PostgreSQL when data is highly relational, requires complex joins, or when ACID transactions across multiple collections are frequently needed.
- Use a time-series database (InfluxDB, TimescaleDB) for sensor data or metrics - MongoDB's document model is inefficient for high-frequency time-series writes.
Reference Files
https://www.mongodb.com/docs/manual/https://mongoosejs.com/docs/guide.html