MongoDB 入土基础笔记

85次阅读
没有评论

共计 6092 个字符,预计需要花费 16 分钟才能阅读完成。

目录

  1. 快速开始:安装与连通性
  2. 基础操作:CRUD、聚合与 explain()
  3. 数据建模:文档结构与常见反模式
  4. 索引实战:类型、组合与覆盖查询
  5. 事务实战:单机、副本集与 分片事务
  6. 高可用:复制集(Replica Set)
  7. 水平扩展:分片(Sharding)
  8. 性能与可观测:Profiler、慢查询、连接池调优
  9. 安全加固:认证、RBAC、SCRAM、TLS
  10. 备份与恢复:mongodump / mongorestore 与快照
  11. 常用高级特性:更改流、TTL、模式校验、时序集合、地理 / 全文
  12. 应用接入与连接池:Node.js 与 Python
  13. 常见踩坑清单与排错思路

1) 快速开始:安装与连通性

1.1 使用 Docker(推荐本地试用)

docker run -d --name mongo \
  -p 27017:27017 \
  -v $PWD/data:/data/db \
  mongodb/mongodb-community-server:latest

官方社区版镜像(Docker Hub)见“mongodb/mongodb-community-server”。(MongoDB)

1.2 mongosh 连接

# 安装 mongosh(也可用独立安装包)# 之后连接本地实例:mongosh "mongodb://localhost:27017"

mongosh 是官方交互式 Shell,支持 CRUD、聚合与管理脚本。(MongoDB)

1.3 GUI:Compass

  • Windows/macOS/Linux 一键安装,内置索引面板、聚合构建器与 Explain 视图。(MongoDB)

2) 基础操作:CRUD、聚合与 explain()

// mongosh
use shop
db.orders.insertMany([{userId:1, amount: 99, ts: new Date()}, {userId:1, amount: 39, ts: new Date()}])
db.orders.find({userId:1}).sort({ts:-1}).limit(10)

// 聚合例:按用户统计消费
db.orders.aggregate([
  {$match: {ts: {$gte: ISODate("2025-01-01")}}},
  {$group: {_id:"$userId", total: {$sum:"$amount"}, cnt: {$sum:1}}},
  {$sort: {total:-1}}
])

// 性能剖析:查看优化器选择与索引使用
db.orders.explain("executionStats").find({userId:1}).sort({ts:-1}).limit(10)

聚合管道与主要阶段、$lookup、窗口函数等详见官方手册;explain() 可查看计划与统计。(MongoDB)


3) 数据建模:文档结构与常见反模式

  • 按查询建模:围绕读写路径组织文档,而非机械地“表 - 外键”搬运。
  • 关注 反模式:无界数组、巨型文档、过多集合、过度归一化 / 反归一化混乱等,都是性能杀手。(MongoDB)

进一步学习可看 MongoDB University 的模式设计课程与案例。(learn.mongodb.com)


4) 索引实战:类型、组合与覆盖查询

4.1 常见索引类型

  • 单键 / 复合索引(B-Tree)
  • 多键索引:数组 / 嵌套数组字段自动成为多键索引。(mongodb.ac.cn)
  • TTL 索引:按 expireAfterSeconds 自动过期文档(适合日志、会话)。(MongoDB)
  • 文本索引:基本全文搜索(注意它与 Atlas Search 的区别)。(MongoDB)
  • 2dsphere:地理空间查询 / 排序。(mongodb.net.cn)
  • 通配符(Wildcard)索引:应对动态 / 未知字段键。(MongoDB)
  • 部分索引:只为满足过滤条件的文档建立索引,节省空间。(MongoDB)

4.2 组合索引与排序

  • 组合索引 字段顺序 要与高频查询的 等值 / 排序 / 范围 模式匹配(等值放前、排序次之、范围最后)。官方“查询优化”专题有覆盖索引与排序注意事项。(MongoDB)

4.3 覆盖查询(Covered Query)

  • 查询条件与返回字段 包含在同一索引时,可不回表,显著减少 IO。可用 explain() 验证。(MongoDB)

小贴士:创建索引后用 db.collection.getIndexes() 检查、用 explain() 验证实际是否命中。


5) 事务实战:单机 / 副本集 / 分片事务

  • MongoDB 支持 多文档事务 (WiredTiger 存储引擎)。在 4.2+ 的分片集群 中也支持 分布式事务。(MongoDB)

mongosh(副本集或分片)示例:

session = db.getMongo().startSession()
session.startTransaction()
try {session.getDatabase("shop").orders.insertOne({userId:2, amount:10})
  session.getDatabase("shop").users.updateOne({id:2}, {$inc:{balance:-10}})
  session.commitTransaction()} catch (e) {session.abortTransaction()
  throw e
}

事务语义、限制与最佳实践详见“Transactions”与“Transactions and Atomicity”。(MongoDB)


6) 高可用:复制集(Replica Set)

  • 至少 3 节点(Primary/Secondary/Secondary)以抗故障,写入 Primary、读取可设优先级策略。
  • 部署与初始化可参考官方“部署副本集”教程。(MongoDB)

7) 水平扩展:分片(Sharding)

  • 适合 超大数据量 / 高吞吐,需要选择合理的 Shard Key,并在集合上 shardCollection
  • 默认 Chunk 大小为 128MB,Balancer 负责跨分片均衡。(MongoDB)

基本流程(mongosh 连接 mongos):

sh.enableSharding("shop")
db.adminCommand({
  shardCollection: "shop.orders",
  key: {userId: 1, ts: -1} // 示例
})

分片操作命令与管理流程详见手册。(MongoDB)


8) 性能与可观测:Profiler、慢查询、连接池

8.1 Profiler 与慢查询

  • 开启 Database Profiler 记录慢操作;结合 explain("executionStats") 定位表扫 / 索引、排序与回表。(MongoDB)

8.2 连接池调优(驱动侧)

  • 关键参数:maxPoolSizeminPoolSizeconnectTimeoutMSsocketTimeoutMSmaxTimeMS(服务器取消长任务)。
  • 计算 应用侧总连接 mongod 入站连接 时要考虑副本集成员数与应用实例数。详见官方“连接池设置调优”。(mongodb.ac.cn)

9) 安全加固:认证、RBAC、SCRAM、TLS

  • 启用访问控制(授权 / 认证),创建 admin 用户与业务读写用户。(mongodb.ac.cn)
  • 默认认证机制为 SCRAM(推荐 SCRAM-SHA-256),所有官方驱动均支持。(mongodb.ac.cn)

最小示例:

# 1) 无认证启动一次,创建管理员
mongod --dbpath /data/db
# 另开终端
mongosh
use admin
db.createUser({user:"root", pwd: passwordPrompt(), roles:["userAdminAnyDatabase","readWriteAnyDatabase"]})
# 2) 开启认证(mongod.conf)security:
  authorization: enabled
# 3) 重启并用凭证连接
mongod --config /etc/mongod.conf
mongosh "mongodb://root@localhost/admin" --password

开启访问控制与 SCRAM 认证的自托管流程详见官方教程。(mongodb.ac.cn)


10) 备份与恢复:工具与快照

  • 自管环境常用 mongodump / mongorestore(逻辑备份),也可使用 文件系统快照 或 Atlas 托管备份。
  • 分片集群的备份 / 恢复有 专门流程,务必按官方步骤执行。(MongoDB)

示例:

# 逻辑备份整个实例到 dump/ 目录
mongodump --uri="mongodb://root:***@localhost/admin"

# 从归档恢复(单文件)mongorestore --archive=full-2025-10-11.archive --nsInclude="shop.*"

11) 常用高级特性

  • Change Streams(更改流):订阅集合 / 库 / 全集群数据变更事件(无需手动 tail oplog),支持前 / 后镜像(6.0+)。(MongoDB)
  • TTL 索引:自动过期数据(会话、日志)。(MongoDB)
  • Schema Validation(JSON Schema):在服务端做结构约束与校验。(mongodb.asprain.cn)
  • Time Series(时序集合):写入按 bucket 聚合,压缩与查询更高效,适合监控 /IoT。(MongoDB)
  • 2dsphere 地理查询 文本索引 见第 4 节。(mongodb.net.cn)

12) 应用接入与连接池:Node.js / Python

12.1 Node.js 官方驱动

npm i mongodb
// src/db.ts
import {MongoClient} from "mongodb";

const uri = process.env.MONGO_URI || "mongodb://root:pass@localhost:27017/?authSource=admin";
export const client = new MongoClient(uri, {
  maxPoolSize: 200,   // 并发连接上限
  minPoolSize: 10,    // 预热连接
  connectTimeoutMS: 5000,
  socketTimeoutMS: 15000,
});

export async function run() {await client.connect();
  const col = client.db("shop").collection("orders");
  const doc = await col.find({userId: 1}).sort({ts: -1}).limit(10).toArray();
  console.log(doc);
}

Node.js 驱动 Quick Start / Get Started 与文档总览。连接池参数与调优见第 8 节。(MongoDB)

12.2 Python(PyMongo)

pip install "pymongo>=4.10"
# app.py
from pymongo import MongoClient
client = MongoClient(
    "mongodb://root:pass@localhost:27017/?authSource=admin",
    maxPoolSize=200, minPoolSize=10,
    socketTimeoutMS=15000, connectTimeoutMS=5000,
)
col = client["shop"]["orders"]
print(list(col.find({"userId": 1}).sort("ts", -1).limit(10)))

PyMongo 入门与官方文档。(MongoDB)


13) 常见踩坑清单与排错思路

  1. 分页深页慢 :用 延迟游标(基于上次最大键)替代 skip/limit 深翻;或使用覆盖索引 +$gt/$lt。参见“查询优化”。(MongoDB)
  2. 函数包裹导致索引失效:把 DATE(ts)=... 改成范围查询(ts >= ... AND ts < ...)。
  3. 复合索引顺序不当:将等值字段放前,排序字段其后,范围字段最后;用 explain() 验证是否 **“IXSCAN + SORT=0”**。(MongoDB)
  4. 分片键选择不佳 :不要用低基数 / 热点键;必要时选择 复合分片键(含时间 + 业务维度)。(MongoDB)
  5. 以为“跨分片不支持事务”:自 4.2 起,支持分布式事务,但注意长事务会放大资源占用,谨慎使用。(MongoDB)
  6. 连接数暴涨:检查应用实例数 × 副本集成员数 × maxPoolSize 的乘积,按需下调;正确设置 connectTimeoutMS/socketTimeoutMS。(mongodb.ac.cn)
  7. 未开启认证:生产务必启用 RBAC + SCRAM,并最小化权限。(mongodb.ac.cn)
  8. 备份不可用:分片集群直接 mongodump/mongorestore 需要遵循专用流程;生产建议快照 + 定期演练恢复。(MongoDB)

附录 · 常用命令速查

// 创建索引(复合 + 排序友好)db.orders.createIndex({userId:1, ts:-1})

// TTL(30 天过期)db.sessions.createIndex({expireAt:1}, {expireAfterSeconds: 0})
// 文档中将 expireAt 写成未来时间点

// 文本索引
db.posts.createIndex({content: "text", title: "text"})

// 地理索引
db.stores.createIndex({location: "2dsphere"})

// Wildcard
db.events.createIndex({"payload.$**": 1})

// JSON Schema 校验
db.createCollection("users", {
  validator: {
    $jsonSchema: {
      bsonType: "object",
      required:["name","age"],
      properties: {age: { bsonType:"int", minimum:0} }
    }
  }
})

各类索引 / 校验的详细语义与限制,见前述相应索引与验证章节的官方文档。(MongoDB)


参考与延伸阅读(官方)

  • MongoDB 手册(8.0 当前)导航:CRUD/ 聚合 / 索引 / 事务 / 复制 / 分片 / 性能 / 安全等。(mongodb.ac.cn)
  • 聚合、$lookup、窗口函数。(MongoDB)
  • 查询优化、覆盖查询、explain()。(MongoDB)
  • 索引类型:TTL、文本、2dsphere、Wildcard、多键。(MongoDB)
  • 事务与分片事务。(MongoDB)
  • 复制集与分片命令、Chunk 默认大小。(MongoDB)
  • Profiler 与连接池调优。(MongoDB)
  • 安全与 SCRAM。(mongodb.ac.cn)
  • 备份恢复工具指南。(MongoDB)
  • 更改流与时序集合。(MongoDB)
  • Node.js / PyMongo 驱动入门。(MongoDB)

正文完
 0
一诺
版权声明:本站原创文章,由 一诺 于2025-10-11发表,共计6092字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)
验证码