MongoDBNotes

附录:附录:MongoDB 速查手册

zjc 于 2026-02-01 发布

这是《MongoDB 零基础实战指南》的独立章节版。本章从概念、实操和生产排查三个视角展开,代码块保留了原书可直接运行的版本。 本速查以 MongoDB 7.x / 8.x 通用用法为主。不同版本命令、参数和默认值可能变化,生产操作前以当前版本文档为准。

核心概念

概念 说明
Database 数据库
Collection 集合
Document BSON 文档
Field 字段
_id 文档唯一标识
Replica Set 副本集
Primary 接收写入
Secondary 同步副本
Oplog 复制日志
Shard 数据分片
mongos 分片路由
Config Server 分片元数据
WiredTiger 默认存储引擎

常用端口

组件 默认端口
mongod / mongos 27017

生产环境只监听内网地址,不应暴露公网。

连接

单节点:

mongodb://user:password@mongo1:27017/shop?authSource=admin

副本集:

mongodb://user:password@mongo1:27017,mongo2:27017,mongo3:27017/shop?replicaSet=rs0&authSource=admin

分片集群:

mongodb://user:password@mongos1:27017,mongos2:27017/shop?authSource=admin

Docker 快速启动

docker run -d \
  --name mongo \
  -p 27017:27017 \
  -e MONGO_INITDB_ROOT_USERNAME=admin \
  -e MONGO_INITDB_ROOT_PASSWORD=secret123 \
  -v mongo-data:/data/db \
  mongo:7.0

进入 shell:

docker exec -it mongo mongosh -u admin -p secret123

数据库与集合

show dbs
use shop
show collections

创建集合:

db.createCollection("orders")

删除集合:

db.orders.drop()

查看统计:

db.orders.stats()

插入

db.orders.insertOne({
  _id: "o_1",
  user_id: "u_1",
  status: "CREATED",
  amount: NumberDecimal("100.00")
})
db.orders.insertMany([
  { _id: "o_2", user_id: "u_1", status: "CREATED" },
  { _id: "o_3", user_id: "u_2", status: "CREATED" }
], { ordered: false })

查询

db.orders.findOne({ _id: "o_1" })
db.orders.find({
  user_id: "u_1",
  status: { $in: ["CREATED", "PAID"] }
})
db.orders.find(
  { user_id: "u_1" },
  { status: 1, amount: 1, created_at: 1 }
).sort({ created_at: -1 }).limit(20)

更新

db.orders.updateOne(
  { _id: "o_1", status: "WAIT_PAY" },
  {
    $set: { status: "PAID", paid_at: new Date() },
    $inc: { version: 1 }
  }
)

常用操作符:

操作符 说明
$set 设置字段
$unset 删除字段
$inc 增减
$push 数组追加
$pull 数组删除
$addToSet 去重追加
$currentDate 更新时间

删除

db.orders.deleteOne({ _id: "o_1" })
db.orders.deleteMany({ status: "CLOSED", created_at: { $lt: cutoff } })

索引

db.orders.createIndex({ user_id: 1, created_at: -1 })
db.orders.createIndex(
  { order_no: 1 },
  { unique: true }
)
db.sessions.createIndex(
  { expires_at: 1 },
  { expireAfterSeconds: 0 }
)
db.orders.getIndexes()
db.orders.dropIndex("user_id_1_created_at_-1")

执行计划

db.orders.find({ user_id: "u_1" }).explain("executionStats")

重点:

winningPlan
IXSCAN / COLLSCAN
keysExamined
docsExamined
nReturned
SORT

聚合

db.orders.aggregate([
  { $match: { status: "PAID" } },
  { $unwind: "$items" },
  {
    $group: {
      _id: "$items.sku_id",
      quantity: { $sum: "$items.quantity" },
      amount: { $sum: "$items.price" }
    }
  },
  { $sort: { quantity: -1 } },
  { $limit: 20 }
])

事务

const session = db.getMongo().startSession();

try {
  session.startTransaction({
    readConcern: { level: "snapshot" },
    writeConcern: { w: "majority" }
  });

  session.getDatabase("shop").orders.updateOne(
    { _id: "o_1", status: "WAIT_PAY" },
    { $set: { status: "PAID" } }
  );

  session.commitTransaction();
} catch (e) {
  session.abortTransaction();
} finally {
  session.endSession();
}

副本集

rs.status()
rs.conf()
db.hello()
rs.printSecondaryReplicationInfo()
db.printReplicationInfo()

主动切换:

rs.stepDown(120)

分片

sh.status()
sh.enableSharding("shop")
sh.shardCollection("shop.orders", { tenant_id: 1, user_id: 1 })
sh.isBalancerRunning()
sh.stopBalancer()
sh.startBalancer()

Change Stream

const stream = db.orders.watch([], {
  fullDocument: "updateLookup"
});
const event = stream.next();
db.sync_tokens.updateOne(
  { name: "orders" },
  { $set: { token: event._id, updated_at: new Date() } },
  { upsert: true }
)

读写关注

db.orders.insertOne(
  { _id: "o_1", status: "CREATED" },
  { writeConcern: { w: "majority", j: true, wtimeout: 3000 } }
)
db.orders.find({ _id: "o_1" }).readPref("primary")

监控

db.serverStatus()
db.currentOp({ active: true, secs_running: { $gte: 60 } })

关键指标:

connections_current
opcounters
query_latency
cache_bytes
cache_dirty_bytes
pages_read_into_cache
replication_lag_seconds
oplog_window
disk_usage
transactions_write_conflicts

备份恢复

mongodump --uri="mongodb://backup:pass@mongo1,mongo2,mongo3/shop?replicaSet=rs0" --gzip --out=/backup
mongorestore --uri="mongodb://admin:pass@target:27017/admin" --gzip --drop /backup

大规模生产环境优先使用快照或平台备份,并定期恢复演练。

安全检查

  1. 启用访问控制;
  2. 禁止公网暴露;
  3. 按服务创建最小权限用户;
  4. 启用 TLS;
  5. 敏感字段脱敏;
  6. 审计高危操作;
  7. 密钥进入 KMS 或 Secret;
  8. 定期复核账号权限。

常见错误

错误 排查
Connection refused 进程、端口、bindIp
Authentication failed 密码或 authSource
Not primary 写到 Secondary 或选举中
Duplicate key 唯一索引冲突
Query exceeded memory 排序或聚合无索引
WriteConflict 并发更新同一文档
Not primary and secondary ok 拓扑状态或读偏好

生产上线清单

  1. 副本集至少三数据节点;
  2. 跨故障域部署;
  3. 认证和 TLS 开启;
  4. 业务用户最小权限;
  5. 高频查询有索引;
  6. 文档和数组大小可控;
  7. 一致性矩阵明确;
  8. 备份和恢复演练完成;
  9. 监控告警接入;
  10. 容量模型和扩容预案完成;
  11. 分片键经过评审;
  12. 升级回滚方案明确。

思考题

  1. 你的核心集合使用什么读写关注组合?
  2. 最近一次慢查询 Top 10 是否都验证过 explain?
  3. 副本集 oplog 窗口能覆盖多长故障?
  4. 备份能否恢复用户、索引和分片元数据?
  5. 工作集是否已经接近内存上限?