MongoDB
Updated: May 22, 2026Categories: Query, Backend, NoSQL
Printed from:
MongoDB Query Language (MQL) Cheatsheet
1. Connection and Basic Commands
Connecting to MongoDB
Bash
123456789# Connect to local MongoDB instance (mongosh is the current shell; legacy `mongo` is removed)
mongosh
# Connect to remote MongoDB instance
mongosh "mongodb://username:password@host:port/database"
# Connect using MongoDB Atlas
mongosh "mongodb+srv://cluster.mongodb.net/database" --username username
Basic Shell Commands
JavaScript
123456789// Show all databases
show dbs
// Switch/create database
use myDatabase
// Show collections in current database
show collections
2. Database and Collection Operations
Create and Drop
JavaScript
12345678910111213141516171819202122// Create a database (happens automatically when first used)
use newDatabase
// Create a collection
db.createCollection("users")
// Create a time series collection (MongoDB 5.0+)
db.createCollection("sensorReadings", {
timeseries: {
timeField: "timestamp",
metaField: "sensorId",
granularity: "seconds"
}
})
// Drop a database
use myDatabase
db.dropDatabase()
// Drop a collection
db.users.drop()
3. Document Structure and BSON Types
Document Example
JavaScript
12345678910111213{
_id: ObjectId("5f8d7a1b9d3b2a1b9c1d2e3f"),
name: "John Doe",
age: 30,
active: true,
tags: ["developer", "mongodb"],
address: {
street: "123 Code Lane",
city: "Techville"
},
createdAt: ISODate("2023-09-09T12:00:00Z")
}
BSON Types
String: Text dataInt32/Int64: Whole numbersDouble: Floating-point numbersBoolean: true/falseArray: List of valuesObject: Embedded documentsObjectId: Unique document identifierDate: TimestampNull: Absence of valueTimestamp: Internal MongoDB useBinData: Raw binary dataDecimal128: High-precision decimalUUID: BSON binary subtype 4 (native in MongoDB 8.0+)
4. CRUD Operations
Insert Documents
JavaScript
12345678910111213// Insert a single document
db.users.insertOne({
name: "Alice",
age: 28,
email: "alice@example.com"
})
// Insert multiple documents
db.users.insertMany([
{ name: "Bob", age: 35 },
{ name: "Charlie", age: 42 }
])
Find Documents
JavaScript
123456789101112131415161718192021222324// Find all documents
db.users.find()
// Find with specific criteria
db.users.find({ age: { $gt: 30 } })
// Find specific fields (projection)
db.users.find(
{ age: { $gt: 25 } },
{ name: 1, age: 1, _id: 0 }
)
// Limit and sort results
db.users.find()
.limit(5)
.sort({ age: 1 })
// Atomic find-and-modify
db.users.findOneAndUpdate(
{ name: "Alice" },
{ $set: { lastSeen: new Date() } },
{ returnDocument: "after" }
)
Update Documents
JavaScript
123456789101112131415161718192021222324252627282930313233// Update a single document
db.users.updateOne(
{ name: "Alice" },
{ $set: { age: 29 } }
)
// Update multiple documents
db.users.updateMany(
{ age: { $lt: 30 } },
{ $inc: { age: 1 } }
)
// Update with an aggregation pipeline (MongoDB 4.2+)
db.users.updateMany(
{},
[
{ $set: { fullName: { $concat: ["$firstName", " ", "$lastName"] } } }
]
)
// Upsert
db.users.updateOne(
{ email: "new@example.com" },
{ $setOnInsert: { createdAt: new Date() }, $set: { active: true } },
{ upsert: true }
)
// Replace entire document
db.users.replaceOne(
{ name: "Bob" },
{ name: "Robert", age: 36 }
)
Delete Documents
JavaScript
123456// Delete a single document
db.users.deleteOne({ name: "Alice" })
// Delete multiple documents
db.users.deleteMany({ age: { $lt: 25 } })
Bulk Writes
JavaScript
123456db.users.bulkWrite([
{ insertOne: { document: { name: "Dana" } } },
{ updateOne: { filter: { name: "Bob" }, update: { $set: { active: true } } } },
{ deleteOne: { filter: { name: "Charlie" } } }
])
5. Query Operators
Comparison Operators
JavaScript
123456789101112// Equality
db.users.find({ age: { $eq: 30 } })
// Greater than/less than
db.users.find({ age: { $gt: 25, $lt: 40 } })
// In array of values
db.users.find({ status: { $in: ["active", "pending"] } })
// Not equal
db.users.find({ status: { $ne: "inactive" } })
Logical Operators
JavaScript
12345678910111213141516// AND
db.users.find({
$and: [
{ age: { $gt: 25 } },
{ status: "active" }
]
})
// OR
db.users.find({
$or: [
{ age: { $lt: 30 } },
{ status: "VIP" }
]
})
Text and Regex Operators
JavaScript
123456// Text search (requires a text index)
db.articles.find({ $text: { $search: "mongodb database" } })
// Regex matching — prefer anchored expressions to leverage indexes
db.users.find({ name: { $regex: "^John", $options: "i" } })
Array Operators
JavaScript
123456789// All values must match
db.products.find({ tags: { $all: ["new", "sale"] } })
// Element matches multiple criteria within a single array element
db.orders.find({ items: { $elemMatch: { sku: "A1", qty: { $gte: 2 } } } })
// Array length
db.posts.find({ comments: { $size: 0 } })
6. Aggregation Framework
Basic Pipeline
JavaScript
123456789101112131415161718db.sales.aggregate([
// Match stage
{ $match: { status: "completed" } },
// Group stage
{ $group: {
_id: "$product",
totalRevenue: { $sum: "$amount" },
avgPrice: { $avg: "$price" }
}},
// Sort stage
{ $sort: { totalRevenue: -1 } },
// Limit stage
{ $limit: 5 }
])
Common Aggregation Stages
$match: Filter documents (place early to use indexes)$group: Group by key and perform calculations$sort: Order results$project: Shape output documents$set/$addFields: Add or replace fields$unset: Remove fields$lookup: Join with another collection (supports correlated sub-pipelines)$unwind: Deconstruct array fields$facet: Run multiple sub-pipelines in parallel$bucket/$bucketAuto: Histogram-style grouping$merge/$out: Write pipeline results to a collection$densify/$fill: Fill gaps in time series data (5.1+)$setWindowFields: Window/analytic functions (5.0+)$vectorSearch/$search: Atlas Vector and full-text search (Atlas only)
Vector Search (Atlas)
JavaScript
12345678910111213db.movies.aggregate([
{
$vectorSearch: {
index: "embedding_index",
path: "plot_embedding",
queryVector: [0.12, -0.04, /* ... */ 0.88],
numCandidates: 200,
limit: 10
}
},
{ $project: { title: 1, score: { $meta: "vectorSearchScore" } } }
])
7. Indexing and Performance
Create Indexes
JavaScript
123456789101112131415161718192021222324// Single field index
db.users.createIndex({ email: 1 })
// Compound index (ESR rule: Equality, Sort, Range)
db.users.createIndex({ status: 1, createdAt: -1, age: 1 })
// Unique index
db.users.createIndex({ email: 1 }, { unique: true })
// Partial index
db.users.createIndex(
{ email: 1 },
{ partialFilterExpression: { active: true } }
)
// TTL index (auto-expires documents)
db.sessions.createIndex({ lastActivity: 1 }, { expireAfterSeconds: 3600 })
// Text index
db.articles.createIndex({ content: "text" })
// Wildcard index
db.products.createIndex({ "attributes.$**": 1 })
Performance Tips
- Apply the ESR rule (Equality → Sort → Range) when designing compound indexes
- Use indexes for frequently queried fields
- Use projection to return only needed fields
- Use
explain("executionStats")to analyze query performance - Prefer
hint()only when the planner consistently picks the wrong index - Avoid unbounded
$regex,$where, and$ninon large collections
8. Schema Validation
JavaScript
1234567891011121314151617181920212223// Create collection with JSON Schema validation
db.createCollection("users", {
validator: {
$jsonSchema: {
bsonType: "object",
required: ["name", "email"],
properties: {
name: {
bsonType: "string",
description: "must be a string"
},
email: {
bsonType: "string",
pattern: "^.+@.+$",
description: "must be a valid email"
}
}
}
},
validationLevel: "moderate",
validationAction: "error"
})
9. GridFS for Large Files
JavaScript
1234567891011// Store files larger than the 16 MB BSON document limit
const { MongoClient, GridFSBucket } = require("mongodb");
const fs = require("fs");
const client = await MongoClient.connect(uri);
const db = client.db("media");
const bucket = new GridFSBucket(db, { bucketName: "uploads" });
fs.createReadStream("myfile.txt")
.pipe(bucket.openUploadStream("myfile.txt"));
10. Transactions and Consistency
JavaScript
1234567891011121314151617181920212223242526// Multi-document ACID transaction (replica set or sharded cluster required)
const session = db.getMongo().startSession();
session.startTransaction({
readConcern: { level: "snapshot" },
writeConcern: { w: "majority" }
});
try {
const users = session.getDatabase("mydb").users;
const accounts = session.getDatabase("mydb").accounts;
users.insertOne({ name: "New User" }, { session });
accounts.updateOne(
{ _id: accountId },
{ $inc: { balance: -100 } },
{ session }
);
session.commitTransaction();
} catch (error) {
session.abortTransaction();
throw error;
} finally {
session.endSession();
}
Tip: Keep transactions short. For most workloads, a well-designed single-document update is faster and atomically consistent without a transaction.
11. Replication and Sharding Basics
Replication
- Primary node handles writes
- Secondary nodes replicate data via the oplog
- Provides high availability and read scaling (with read preferences)
- Use replica sets for fault tolerance; majority write concern protects against rollbacks
Sharding
- Distribute data across multiple shards (each a replica set)
- Shard key determines data distribution — choose for high cardinality and even write distribution
- Hashed shard keys spread writes; ranged keys preserve locality
- Sharded clusters support resharding online (5.0+) and unsharding a collection (8.0+)
12. Common Patterns
Embedded vs Referenced Documents
JavaScript
1234567891011121314151617181920// Embedded (denormalized) — best for data accessed together and bounded in size
{
_id: ObjectId("..."),
name: "Product",
reviews: [
{ user: "Alice", rating: 5 },
{ user: "Bob", rating: 4 }
]
}
// Referenced (normalized) — best for unbounded or independently mutated data
// users collection
{ _id: ObjectId("alice_id"), name: "Alice" }
// products collection
{
_id: ObjectId("..."),
name: "Product",
reviews: [ObjectId("alice_id"), ObjectId("bob_id")]
}
Change Streams
JavaScript
123456789// React to data changes in real time (replica sets and sharded clusters)
const stream = db.orders.watch([
{ $match: { "fullDocument.status": "completed" } }
]);
for await (const change of stream) {
console.log(change.operationType, change.fullDocument);
}
Client-Side Field Level Encryption / Queryable Encryption
- CSFLE encrypts sensitive fields client-side using a Key Management Service
- Queryable Encryption (GA in 6.0+, expanded operators in 7.0/8.0) supports equality and range queries on encrypted data without the server seeing plaintext
13. Performance Optimization Tips
- Design indexes for your query shapes using the ESR rule
- Avoid
$where, unbounded$regex, and$ninon large collections - Limit result sets and paginate with range queries (not large
skipvalues) - Use projections to reduce network and working-set size
- Denormalize for read-heavy access patterns; reference for unbounded data
- Push computation server-side with the aggregation framework
- Profile with
explain("executionStats")and the database profiler - Use time series collections for metrics/IoT data instead of capped collections
- Set appropriate read/write concerns;
majorityis the safe default for writes - Monitor with MongoDB Atlas,
mongostat,mongotop, and the Performance Advisor
14. Deprecated / Removed (Know Before You Upgrade)
- Legacy
mongoshell — replaced bymongosh db.copyDatabase()andcloneCollection— removed; usemongodump/mongorestoreor$out/$mergegeoHaystackindexes — removed in 5.0; use2dsphereMMAPv1storage engine — removed in 4.2; WiredTiger is the default and only supported engine- Map-Reduce — deprecated; use the aggregation framework (
$group,$accumulator,$function) - TLS 1.0/1.1 — disabled by default in modern releases
Additional Resources
- MongoDB Documentation: https://www.mongodb.com/docs/
- MongoDB University: https://learn.mongodb.com
- MongoDB Compass: GUI for MongoDB
- MongoDB Atlas: Managed cloud database with Search and Vector Search
Note: Always refer to the latest MongoDB documentation for the most up-to-date information and best practices.
Continue Learning
Discover more cheatsheets to boost your productivity