mongodb
MongoDB - NoSQL document database with flexible schema design, aggregation pipelines, indexing strategies, and Spring Data integration
What this skill does
# MongoDB - Document Database Patterns
## Overview
MongoDB is a document-oriented NoSQL database that stores data in flexible, JSON-like documents. It excels at handling unstructured or semi-structured data, hierarchical relationships, and scenarios requiring horizontal scaling.
**Key Features**:
- Flexible schema (schemaless documents)
- Rich query language with secondary indexes
- Aggregation framework for analytics
- Horizontal scaling (sharding)
- Replica sets for high availability
- Change streams for real-time data
- Geospatial and full-text search
**When to Use MongoDB**:
- Rapidly evolving schemas
- Hierarchical/nested data (embedded documents)
- Real-time analytics with aggregation
- Geospatial applications
- Content management systems
- IoT data ingestion
- Catalog/inventory systems
**When NOT to Use MongoDB**:
- Complex multi-table joins (use RDBMS)
- ACID transactions across many documents (improved in 4.0+, but limited)
- Strict schema enforcement requirements
## Schema Design Fundamentals
### Document Structure
```javascript
// MongoDB document (BSON format)
{
"_id": ObjectId("507f1f77bcf86cd799439011"), // Primary key (auto-generated)
"email": "[email protected]",
"name": "Alice Johnson",
"profile": { // Embedded document
"bio": "Software developer",
"avatar": "https://example.com/avatar.jpg",
"social": {
"twitter": "@alice",
"github": "alice-dev"
}
},
"tags": ["developer", "python", "mongodb"], // Array field
"createdAt": ISODate("2024-01-15T10:30:00Z"),
"updatedAt": ISODate("2024-01-20T14:22:00Z")
}
```
### Embedded vs Referenced Documents
**Embedded (Denormalized)** - Store related data in same document:
```javascript
// Embedded: Good for 1:1 or 1:Few relationships
// User with embedded address
{
"_id": ObjectId("..."),
"name": "Alice",
"address": {
"street": "123 Main St",
"city": "San Francisco",
"zipCode": "94102"
}
}
// Embedded: Order with line items (1:Many bounded)
{
"_id": ObjectId("..."),
"orderNumber": "ORD-2024-001",
"customer": { "name": "Alice", "email": "[email protected]" },
"items": [
{ "productId": "SKU001", "name": "Widget", "quantity": 2, "price": 29.99 },
{ "productId": "SKU002", "name": "Gadget", "quantity": 1, "price": 49.99 }
],
"total": 109.97
}
```
**When to Embed**:
- Data is queried together frequently
- Child data doesn't make sense without parent
- 1:1 or 1:Few relationships
- Child data is bounded (won't grow unbounded)
- Data doesn't need to be accessed independently
**Referenced (Normalized)** - Store references to other documents:
```javascript
// Referenced: Good for 1:Many unbounded or Many:Many
// User document
{
"_id": ObjectId("user123"),
"name": "Alice",
"email": "[email protected]"
}
// Posts collection (references user)
{
"_id": ObjectId("post456"),
"authorId": ObjectId("user123"), // Reference to user
"title": "MongoDB Schema Design",
"content": "...",
"commentCount": 42
}
// Comments collection (references post)
{
"_id": ObjectId("comment789"),
"postId": ObjectId("post456"), // Reference to post
"authorId": ObjectId("user999"), // Reference to commenter
"text": "Great article!",
"createdAt": ISODate("2024-01-20T10:00:00Z")
}
```
**When to Reference**:
- Many:Many relationships
- 1:Many with unbounded growth (comments, logs)
- Data is accessed independently
- Document size would exceed 16MB limit
- Need atomic updates on referenced document
### Hybrid Pattern (Extended Reference)
```javascript
// Post with denormalized author info + reference
{
"_id": ObjectId("post456"),
"title": "MongoDB Best Practices",
"content": "...",
"author": {
"_id": ObjectId("user123"), // Reference for lookups
"name": "Alice", // Denormalized for display
"avatar": "https://..." // Frequently needed fields
},
"commentCount": 42,
"lastCommentAt": ISODate("...")
}
```
## Query Patterns
### Basic CRUD Operations
```javascript
// Find documents
db.users.find({ email: "[email protected]" })
db.users.find({ age: { $gte: 18, $lte: 65 } })
db.users.find({ tags: { $in: ["developer", "designer"] } })
// Find with projection (select specific fields)
db.users.find(
{ status: "active" },
{ name: 1, email: 1, _id: 0 } // Include name, email; exclude _id
)
// Find one
db.users.findOne({ email: "[email protected]" })
// Insert
db.users.insertOne({ name: "Bob", email: "[email protected]" })
db.users.insertMany([
{ name: "Charlie", email: "[email protected]" },
{ name: "Diana", email: "[email protected]" }
])
// Update
db.users.updateOne(
{ email: "[email protected]" },
{ $set: { name: "Alice Updated", updatedAt: new Date() } }
)
db.users.updateMany(
{ status: "inactive" },
{ $set: { archived: true } }
)
// Upsert (update or insert)
db.users.updateOne(
{ email: "[email protected]" },
{ $set: { name: "New User", createdAt: new Date() } },
{ upsert: true }
)
// Delete
db.users.deleteOne({ email: "[email protected]" })
db.users.deleteMany({ status: "deleted" })
```
### Query Operators
```javascript
// Comparison
db.products.find({ price: { $gt: 100 } }) // Greater than
db.products.find({ price: { $gte: 100 } }) // Greater than or equal
db.products.find({ price: { $lt: 50 } }) // Less than
db.products.find({ price: { $lte: 50 } }) // Less than or equal
db.products.find({ price: { $ne: 0 } }) // Not equal
db.products.find({ category: { $in: ["A", "B"] } }) // In array
db.products.find({ category: { $nin: ["C", "D"] } }) // Not in array
// Logical
db.users.find({ $and: [{ age: { $gte: 18 } }, { status: "active" }] })
db.users.find({ $or: [{ role: "admin" }, { role: "moderator" }] })
db.users.find({ age: { $not: { $lt: 18 } } })
// Element
db.users.find({ middleName: { $exists: true } }) // Field exists
db.users.find({ age: { $type: "number" } }) // Field type
// Array
db.posts.find({ tags: "mongodb" }) // Contains element
db.posts.find({ tags: { $all: ["mongodb", "database"] } }) // Contains all
db.posts.find({ tags: { $size: 3 } }) // Array size
db.posts.find({ "tags.0": "featured" }) // First element
// Embedded documents
db.users.find({ "address.city": "San Francisco" })
db.users.find({ "profile.social.twitter": { $exists: true } })
// Regex
db.users.find({ name: { $regex: /^alice/i } })
db.users.find({ email: { $regex: /@example\.com$/ } })
```
### Update Operators
```javascript
// Field updates
db.users.updateOne(
{ _id: userId },
{
$set: { name: "New Name" }, // Set field value
$unset: { temporaryField: "" }, // Remove field
$rename: { oldName: "newName" }, // Rename field
$inc: { loginCount: 1 }, // Increment
$mul: { price: 1.1 }, // Multiply
$min: { lowestScore: 50 }, // Set if less than current
$max: { highestScore: 100 }, // Set if greater than current
$currentDate: { updatedAt: true } // Set to current date
}
)
// Array updates
db.posts.updateOne(
{ _id: postId },
{
$push: { tags: "new-tag" }, // Add to array
$addToSet: { tags: "unique-tag" }, // Add if not exists
$pop: { tags: 1 }, // Remove last (-1 for first)
$pull: { tags: "old-tag" }, // Remove specific value
$pullAll: { tags: ["a", "b"] } // Remove multiple values
}
)
// Array with modifiers
db.posts.updateOne(
{ _id: postId },
{
$push: {
comments: {
$each: [comment1, comment2], // Add multiple
$sort: { createdAt: -1 }, // Sort after push
$slice: -100 // Keep only last 100
}
}
}
)
// Positional update (update matched array element)
db.posts.updateOne(
{ _id: postId, "comments._id": commentId },
{ $set: { "comments.$.text": "Updated comment" } }
)
Related in toolchain
nextjs-core
IncludedCore Next.js patterns for App Router development including Server Components, Server Actions, route handlers, data fetching, and caching strategies
nextjs-v16
IncludedNext.js 16 migration guide (async request APIs, "use cache", Turbopack)
vitest
IncludedVitest - Modern TypeScript testing framework with Vite-native performance, ESM support, and TypeScript-first design
mcp-protocol-builder
IncludedMCP (Model Context Protocol) - Build AI-native servers with tools, resources, and prompts. TypeScript/Python SDKs for Claude Desktop integration.
golang-database-patterns
IncludedGo database integration patterns using sqlx, pgx, and migration tools like golang-migrate
sveltekit
IncludedSvelteKit - Full-stack Svelte framework with file-based routing, SSR/SSG, form actions, and adapters for deployment