The legacy mongo shell is gone — use mongosh.
Sharded transactions are stable (4.2+), time-series collections landed in 5, queryable encryption + clustered
collections in 6, JSON Schema validation has been around since 3.6. License changed to SSPL in 2018 — community
forks (FerretDB, Percona)
exist if you need OSS-pure. This sheet targets MongoDB 7.
Install · connectSetup
bash
# macOS — Homebrew tap
brew tap mongodb/brew
brew install mongodb-community@7.0
brew services start mongodb/brew/mongodb-community
# Linux — official repo (Debian/Ubuntu)
# See https://www.mongodb.com/docs/manual/installation/ for the apt key block
sudo systemctl enable --now mongod
# Docker — disposable dev instance
docker run --name mongo -p 27017:27017 -d mongo:7
# Modern shell — mongosh (the legacy "mongo" binary is gone in 6+)
mongosh # default localhost
mongosh "mongodb://user:pw@host:27017/shop"
mongosh "mongodb+srv://cluster.example/shop?retryWrites=true&w=majority"
# Python driver
pip install "pymongo>=4" "motor>=3" # sync + async
# Ping
mongosh --eval 'db.runCommand({ ping: 1 })'
The shellmongosh essentials
use shop
Switch database. Creates it on first write.
show dbs / show collections
Inventory.
db.getCollection("user-events").find()
Quote collection names with hyphens.
db.stats() / db.t.stats()
Sizes, counts, index footprint.
db.t.countDocuments(q)
Accurate count. Preferred over deprecated .count().
db.t.estimatedDocumentCount()
Fast metadata count. Use for "roughly N".
db.t.drop() / db.dropDatabase()
Destructive. Wrap in a script with confirmation in prod.
it
Iterate the last cursor.
load("script.js")
Run a JS file.
db.adminCommand({"{ currentOp: 1 }"})
In-flight operations — find the runaway query.
Beyond JSONBSON types
ObjectId()
12-byte default _id. Time-ordered — cheap for sort-by-creation.
UUID()
128-bit. Use uuidRepresentation="standard" in pymongo.
ISODate("2026-05-18T00:00:00Z") / new Date()
UTC datetime — 8 bytes.
NumberDecimal("9.99")
128-bit decimal. Preferred for money over double.
NumberLong("9007199254740993")
64-bit integer. JS native numbers are 53-bit.
NumberInt(7)
Force 32-bit int (default in JS is double).
BinData(0, base64)
Binary blob with subtype.
DBRef(coll, id, db)
Legacy — resolve manually with $lookup instead.
null vs $exists: false
Stored null vs missing field — very different queries.
insert · find · update · deleteCRUD
Insert
db.t.insertOne({"{ _id, ... }"})
Returns { insertedId }. Generates _id if omitted.
db.t.insertMany([d1, d2], {"{ ordered: false }"})
Unordered keeps going after a failure — faster bulk loads.
// Single field, ascending
db.users.createIndex({ email: 1 }, { unique: true });
// Compound — leftmost-prefix rule. Order matters:
// can serve queries on {customerId}, {customerId, placedAt}, but not {placedAt} alone.
db.orders.createIndex({ customerId: 1, placedAt: -1 });
// Partial — index only the rows that match the filter
db.users.createIndex(
{ lastLoginAt: -1 },
{ partialFilterExpression: { active: true } }
);
// TTL — expire docs N seconds after the field
db.sessions.createIndex({ createdAt: 1 }, { expireAfterSeconds: 3600 });
// Wildcard — index every field under a path
db.events.createIndex({ "metadata.$**": 1 });
// Text — full-text search
db.posts.createIndex({ title: "text", body: "text" });
db.posts.find({ $text: { $search: "redis cache" } });
// 2dsphere — geo
db.places.createIndex({ location: "2dsphere" });
// Find queries that aren't using an index
db.orders.find({ customerId: 7 }).explain("executionStats");
// Hide an index without dropping (test impact)
db.orders.hideIndex("customerId_1_placedAt_-1");
Embed vs referenceSchema design
Embed
Read together, write together, bounded size. Comments on a blog post.
Reference
Reused across docs, unbounded list, or independently mutable. Users referenced by orders.
Bucket pattern
Group small time-series points into N-per-bucket docs. Cheaper than one-doc-per-event.
Computed pattern
Pre-aggregate on write (e.g. $inc a count) instead of recomputing on read.
Outlier pattern
Move rarely-huge subdocs to a side collection; keep the common case fast.
Schema versioning
Store schema_v: 2 per doc — you can mix versions during migrations.
$jsonSchema validator
Reject malformed inserts at the server. collMod to add.
Time-series collection
First-class type for metrics (5+). Auto-buckets, big disk savings.
Pick the shard key on day one, not day 365.
Changing it later requires a full collection rebuild. Optimize for write distribution + the dominant query — usually a compound of high-cardinality fields, possibly hashed.
Put $match and $project as early as possible in a pipeline.
Mongo can push early $match through an index and skip COLLSCAN entirely. Trim fields with $project before $lookup to cut bytes-shipped.
Use NumberDecimal for money.
JavaScript / BSON doubles can’t represent 0.1 + 0.2 = 0.3. NumberDecimal("9.99") stays exact and aggregates correctly.
Common trapsWatch out for
The 16 MB document limit is a hard cap.
Append-only arrays (chat logs, audit trails, event streams) will eventually hit it — usually in production, late at night. Use bucket pattern or a separate collection.
Range queries on the wrong compound-index column don’t use the index.
With {a:1, b:1, c:1}, a query with equality on a, range on b, equality on c can’t use the c portion — the range on b stops the prefix.
Default writeConcern isn’t always majority.
On older drivers and standalones, writes can ACK before replication. Set w: 'majority' explicitly for anything you can’t afford to lose on failover.
MongoDB is a document-oriented NoSQL database that stores data as BSON (binary JSON) documents. It is used for content management, real-time analytics, catalogs, user profiles, and any use case where flexible schema-less documents are preferable to rigid relational tables.
What is the MongoDB aggregation pipeline?
The aggregation pipeline processes documents through a sequence of stages — $match filters rows, $group aggregates them, $sort orders results, $lookup joins collections, and $project shapes output. Each stage transforms the stream of documents and passes results to the next stage.
How does MongoDB handle transactions?
MongoDB supports multi-document ACID transactions since version 4.0. Start a session with client.startSession(), call session.startTransaction(), run your operations with the session option, then commit or abort. Transactions work across collections and, since 4.2, across shards.
What indexes does MongoDB support?
MongoDB supports single-field, compound, multikey (arrays), text, geospatial, hashed, wildcard, partial, sparse, and TTL indexes. Always run explain('executionStats') to confirm an index is used and check the IXSCAN vs COLLSCAN stage in the winning plan.
Is MongoDB free to use?
Yes. MongoDB Community Server is free to download and self-host. The source-available SSPL license allows self-hosting for most uses. MongoDB Atlas has a free M0 tier. MongoDB Enterprise Advanced is the commercial edition for on-prem deployments with advanced security.