MongoDB Cheatsheet - MongoDB Command Reference

For backend developers using a document store where reads must stay fast. MongoDB shines at schemaless flexible documents, but that freedom costs you unless you index the fields you filter on. By the end you can design CRUD queries against a collection, read explain("executionStats") to confirm an index is used, build an aggregation pipeline with match/group/sort, and know what a replica set guarantees versus what requires sharding.

Databases·43 commands·Last updated 2026-07-21
mongodbnosqlDatabase

Typical Use Case

For developers using MongoDB as their datastore. This sheet covers database and collection operations, document CRUD, query operators, index management, the aggregation pipeline, and replication and sharding. The two points that actually decide production performance are called out explicitly: how query operators are used ($gt, $in and friends, so you filter in the database rather than in memory), and index creation, since an unindexed query on a large collection is a full collection scan. Read the aggregation section closely too — $match placed first and $project used early cut data volume dramatically.

Database 6

show dbs
List all databases
use dbname
Switch to a database (created if absent)
db
Show current database
db.stats()
Show current database stats
db.dropDatabase()
Drop current database
show collections
List all collections in current db

Document CRUD 9

db.collection.insertOne({name: "tom"})
Insert one document
db.collection.insertMany([{...}, {...}])
Insert many documents
db.collection.find()
Find all documents
db.collection.find({age: {$gt: 18}})
Conditional query
db.collection.findOne({name: "tom"})
Find one document
db.collection.updateOne({name: "tom"}, {$set: {age: 20}})
Update one document
db.collection.updateMany({age: {$lt: 18}}, {$set: {status: "minor"}})
Update many documents
db.collection.deleteOne({name: "tom"})
Delete one document
db.collection.deleteMany({age: {$lt: 18}})
Delete many documents

Query Operators 8

{field: value}
Exact match
{field: {$gt: value}}
Greater than ($gte = gte)
{field: {$lt: value}}
Less than ($lte = lte)
{field: {$ne: value}}
Not equal
{field: {$in: [v1, v2]}}
In list
{$and: [{...}, {...}]}
AND condition
{$or: [{...}, {...}]}
OR condition
{field: /regex/i}
Regex match

Index 6

db.collection.createIndex({field: 1})
Create ascending index (-1 descending)
db.collection.createIndex({f1: 1, f2: 1})
Compound index
db.collection.createIndex({field: 1}, {unique: true})
Unique index
db.collection.createIndex({field: 1}, {expireAfterSeconds: 3600})
TTL index (auto-expire)
db.collection.getIndexes()
List all indexes on a collection
db.collection.dropIndex("index_name")
Drop an index

Aggregation 7

db.collection.aggregate([{$match: {age: {$gt: 18}}}])
Match (filter) stage
{$group: {_id: "$field", count: {$sum: 1}}}
Group & count
{$project: {name: 1, _id: 0}}
Field projection
{$sort: {field: -1}}
Sort
{$limit: 10} / {$skip: 20}
Limit / skip
{$unwind: "$arrayField"}
Unwind array field
{$lookup: {from: "other", localField: "id", foreignField: "_id", as: "joined"}}
Join (like SQL JOIN)

Replication & Sharding 7

rs.status()
Show replica set status
rs.conf()
Show replica set config
rs.initiate()
Initialize replica set
rs.add("host:port")
Add a member
rs.remove("host:port")
Remove a member
sh.status()
Show sharded cluster status
sh.enableSharding("dbname")
Enable sharding for a database

Parameter matrix

ParameterEffectExample
use dbname切换数据库(不存在会自动创建)use dbname
show dbs / show collections列出数据库 / 当前库的集合show collections
insertOne / insertMany插入单条 / 批量db.c.insertMany([{...}])
findOne / find查单条 / 全部db.c.find({age: {$gt: 18}})
$gt / $gte / $lt / $lte大小比较{age: {$gte: 18}}
$ne / $in不等于 / 在列表中{_id: {$in: [1, 2]}}
$and / $or逻辑与 / 或{$or: [{a: 1}, {b: 2}]}
/regex/i正则匹配(i 忽略大小写){name: /tom/i}
updateOne / updateMany更新单条 / 批量,配合 $setdb.c.updateMany({}, {$set: {st: "ok"}})
createIndex 复合多字段索引,顺序影响效率db.c.createIndex({f1: 1, f2: 1})
unique: true唯一索引,重复插入报错db.c.createIndex({email: 1}, {unique: true})
expireAfterSecondsTTL 索引,到期自动删除db.c.createIndex({ts: 1}, {expireAfterSeconds: 3600})
$group / $project分组统计 / 字段投影{$group: {_id: "$city", n: {$sum: 1}}}
$unwind / $lookup展开数组 / 跨集合关联{$lookup: {from: "b", localField: "id", as: "j"}}

Common pitfalls

Symptom查询大集合时响应极慢,explain 显示 COLLSCAN。

Cause查询字段没有索引,MongoDB 做全集合扫描。

Fix用 db.collection.getIndexes() 确认索引,对高频查询字段 createIndex;改用 explain("executionStats") 看是否走 IXSCAN。

SymptomupdateMany 后部分字段被覆盖成了 null。

Cause替换语义与更新语义混用,整对象赋值会丢掉未提及字段。

Fix始终配合 $set 只写要改的字段;$set 之外的键不会被删除。

Symptom用 $in 查询数组字段时结果不符合预期。

Cause$in 对数组字段是「包含任一元素即命中」,而不是逐个元素精确匹配。

Fix需要数组包含全部元素时用 $all;需要精确匹配用字段值直接写。

Symptom插入时出现 duplicate key error,但数据里明明没有重复值。

Cause已存在唯一索引,且重复判定按索引字段而非 _id。

Fix用 getIndexes() 找出 unique 索引并检查其字段的实际取值;索引建错字段也会误报。

Symptom集合数据量暴涨,磁盘被占满。

Cause未设置 TTL 索引,日志类文档永久保留。

Fix对时间字段建 expireAfterSeconds 索引;用 db.stats() 确认实际占用。

Symptom聚合管道跑得很慢,内存溢出报错。

Cause$sort 与 $group 在大集合上产生大量内存占用,且 allowDiskUse 未开。

Fix把 $match 放到管道最前缩小数据量;必要时 allowDiskUse: true;确认排序字段有索引。

Symptomuse 一个不存在的库后,它出现在 show dbs 里。

Causeuse 对不存在的库会立即创建。

Fix误建后用 db.dropDatabase() 删除;只想查看库列表不要 use 不存在的名字。

Troubleshooting

  1. 1看查询到底有没有走索引

    db.collection.find({age: {$gt: 18}}).explain("executionStats")

    关注 winningPlan 里是 IXSCAN 还是 COLLSCAN,以及 totalDocsExamined。

  2. 2确认集合的索引

    db.collection.getIndexes()

    排查慢查询第一步:查询字段是否已建索引、索引是否唯一。

  3. 3按字段分组统计

    db.collection.aggregate([{$group: {_id: "$city", n: {$sum: 1}}}])

    $match 放在管道最前可显著减少参与 $group 的数据量。

  4. 4用 TTL 索引自动清理过期数据

    db.logs.createIndex({createdAt: 1}, {expireAfterSeconds: 2592000})

    expireAfterSeconds 单位为秒;字段必须是 BSON Date 类型。

  5. 5确认数据库实际占用

    db.stats()

    含 dataSize 与 indexSize,定位磁盘占用是数据还是索引。

Command Examples

Index before querying, or it slows as data grows

db.orders.createIndex({ customerId: 1, createdAt: -1 }) db.orders.find({ customerId: 'c_1024' }).sort({ createdAt: -1 }).limit(20)

复合索引遵循最左前缀:只有以 customerId 开头的条件能命中。字段顺序按实际查询模式排,常查字段放前面。

Output

createdAt_-1_customerId_1
{ "customerId" : 1, "createdAt" : -1 }
{ "orderId" : "o_8821", "total" : 199.0 }

Aggregation pipeline: put $match first

db.orders.aggregate([ { $match: { status: "paid", createdAt: { $gte: ISODate("2026-09-01") } } }, { $group: { _id: "$customerId", total: { $sum: "$amount" }, n: { $sum: 1 } } }, { $sort: { total: -1 } }, { $limit: 10 } ])

管道按顺序执行,$match 放最前先把数据量缩小,后续 $group/$sort 的开销随之下降。这是聚合性能最关键的一条。

Output

{ "_id" : "c_1024", "total" : 1842.5, "n" : 12 }
{ "_id" : "c_2087", "total" : 1204.0, "n" : 7 }

TTL index for automatic cleanup

db.sessions.createIndex({ createdAt: 1 }, { expireAfterSeconds: 3600 })

适合日志与会话,过期后 MongoDB 自动删除文档,省掉清理任务。注意它是后台周期执行,删除有延迟而非准点发生。

Output

createdAt_1

Common Pitfalls

  • An unindexed query is a full collection scan that collapses as data grows — verify indexes exist before going live.
  • Compound indexes follow the leftmost-prefix rule, so field order must match real query patterns or the index is wasted.
  • Legacy APIs such as db.collection.remove() are deprecated; use deleteMany / deleteOne.
  • TTL deletion runs asynchronously, so expired documents do not vanish immediately and cannot be used for precise point-in-time cleanup.
  • estimatedDocumentCount reads metadata and is fast but can be inaccurate while transactions are in flight; use countDocuments when exactness matters.
  • Sorting on an unindexed field with a large skip degrades to a full scan — paginate with a cursor instead.

Tips

  • MongoDB has no fixed schema by default, but use an ORM like Mongoose for validation.
  • Avoid full collection scans — index large collections and use explain() to inspect the plan.
  • Use at least 3 replica-set nodes for HA; an odd count avoids split-brain.

FAQ

What should I do first when a MongoDB query is slow?

Confirm the filter fields are indexed by checking db.collection.getIndexes(). The flexibility of a document database has a cost: an unindexed query is a full collection scan, which collapses in performance once data grows. Compound indexes follow the leftmost-prefix rule — createIndex({f1: 1, f2: 1}) only accelerates queries whose leading predicate is on f1 — so order fields according to real query patterns.

What does a TTL index do?

db.collection.createIndex({field: 1}, {expireAfterSeconds: 3600}) indexes the field for expiry; when its value is a date or timestamp, MongoDB removes the document once it passes. Logs and sessions are the typical uses — a TTL index on created_at cleans up without a separate maintenance job. Note that deletion runs on a background cycle, so it is delayed rather than instantaneous.

countDocuments versus estimatedDocumentCount?

estimatedDocumentCount reads collection metadata, so it is extremely fast but can be inaccurate while transactions are still committing. countDocuments actually scans and counts, which is slower but reliable. Use countDocuments when accuracy matters and the estimate only to decide whether continuing is worthwhile. Batch jobs often want both: estimate to triage, exact count to verify.

When should I use an aggregation pipeline versus a plain query?

Use find for simple filtering and sorting, where indexes apply directly. Reach for aggregate when you need grouped counts, field transformations or multi-stage processing — it runs stages in order: $match, $group, $project, $sort, $limit. The key optimization is to put $match first so later stages work on a smaller set.

How does a TTL index differ from an ordinary index?

An ordinary index only speeds up lookups. A TTL index does that too but additionally deletes documents once they expire, delegating cleanup to the database. A unique index, created with {unique: true}, prevents duplicate values. All three compose: a session collection can be simultaneously unique and self-expiring.

Official References

Each command links to its official documentation below, so you can verify the latest usage and read deeper.

Maintained by LaoHand

Publicly updated on Jul 21, 2026, continuously proofread against official docs.

Contact Us

Wrong command or description? Send us corrections, business inquiries or product feedback by email.

Contact Us