Backend6 min read

MongoDB

Document-oriented NoSQL database - flexible schemas, horizontal scaling, and rich aggregation pipeline make it ideal for hierarchical or rapidly evolving data models.

MongoDBNoSQLMongooseAggregationAtlas

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

  1. 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.
  2. CRUD operationsMongoDB's query language is JSON-based - intuitive for JavaScript developers and powerful for nested document queries.
  3. Use the aggregation pipelineThe aggregation pipeline is MongoDB's SQL GROUP BY + JOIN - transform, group, and analyze documents in one query.
  4. Index strategicallyMongoDB queries without an index do a full collection scan - fine for small collections, catastrophic at scale.
  5. 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.ts

Examples

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

More skills in this library

Browse all technical skills - Mobile, AI/ML, Web, Backend, Design, and Product.