$npx -y skills add chaterm/terminal-skills --skill mongodbMongoDB 数据库管理
| 1 | # MongoDB 数据库管理 |
| 2 | |
| 3 | ## 概述 |
| 4 | MongoDB 操作、索引优化、分片集群等技能。 |
| 5 | |
| 6 | ## 连接管理 |
| 7 | |
| 8 | ```bash |
| 9 | # 本地连接 |
| 10 | mongosh |
| 11 | mongosh --port 27017 |
| 12 | |
| 13 | # 远程连接 |
| 14 | mongosh "mongodb://hostname:27017" |
| 15 | mongosh "mongodb://user:password@hostname:27017/database" |
| 16 | |
| 17 | # 副本集连接 |
| 18 | mongosh "mongodb://host1:27017,host2:27017,host3:27017/database?replicaSet=rs0" |
| 19 | |
| 20 | # 执行脚本 |
| 21 | mongosh script.js |
| 22 | mongosh --eval "db.collection.find()" |
| 23 | ``` |
| 24 | |
| 25 | ## 基础操作 |
| 26 | |
| 27 | ### 数据库操作 |
| 28 | ```javascript |
| 29 | // 显示数据库 |
| 30 | show dbs |
| 31 | |
| 32 | // 切换/创建数据库 |
| 33 | use mydb |
| 34 | |
| 35 | // 删除数据库 |
| 36 | db.dropDatabase() |
| 37 | |
| 38 | // 数据库统计 |
| 39 | db.stats() |
| 40 | ``` |
| 41 | |
| 42 | ### 集合操作 |
| 43 | ```javascript |
| 44 | // 显示集合 |
| 45 | show collections |
| 46 | |
| 47 | // 创建集合 |
| 48 | db.createCollection("users") |
| 49 | |
| 50 | // 删除集合 |
| 51 | db.users.drop() |
| 52 | |
| 53 | // 集合统计 |
| 54 | db.users.stats() |
| 55 | ``` |
| 56 | |
| 57 | ### CRUD 操作 |
| 58 | ```javascript |
| 59 | // 插入 |
| 60 | db.users.insertOne({ name: "John", age: 30 }) |
| 61 | db.users.insertMany([{ name: "Jane" }, { name: "Bob" }]) |
| 62 | |
| 63 | // 查询 |
| 64 | db.users.find() |
| 65 | db.users.find({ age: { $gt: 25 } }) |
| 66 | db.users.findOne({ name: "John" }) |
| 67 | db.users.find().limit(10).skip(20).sort({ age: -1 }) |
| 68 | |
| 69 | // 更新 |
| 70 | db.users.updateOne({ name: "John" }, { $set: { age: 31 } }) |
| 71 | db.users.updateMany({ age: { $lt: 18 } }, { $set: { status: "minor" } }) |
| 72 | db.users.replaceOne({ name: "John" }, { name: "John", age: 32 }) |
| 73 | |
| 74 | // 删除 |
| 75 | db.users.deleteOne({ name: "John" }) |
| 76 | db.users.deleteMany({ status: "inactive" }) |
| 77 | ``` |
| 78 | |
| 79 | ## 索引管理 |
| 80 | |
| 81 | ```javascript |
| 82 | // 查看索引 |
| 83 | db.users.getIndexes() |
| 84 | |
| 85 | // 创建索引 |
| 86 | db.users.createIndex({ email: 1 }) // 升序 |
| 87 | db.users.createIndex({ name: 1, age: -1 }) // 复合索引 |
| 88 | db.users.createIndex({ email: 1 }, { unique: true }) // 唯一索引 |
| 89 | db.users.createIndex({ location: "2dsphere" }) // 地理索引 |
| 90 | db.users.createIndex({ content: "text" }) // 文本索引 |
| 91 | |
| 92 | // 后台创建(不阻塞) |
| 93 | db.users.createIndex({ field: 1 }, { background: true }) |
| 94 | |
| 95 | // 删除索引 |
| 96 | db.users.dropIndex("email_1") |
| 97 | db.users.dropIndexes() // 删除所有 |
| 98 | |
| 99 | // 索引使用分析 |
| 100 | db.users.find({ email: "test@example.com" }).explain("executionStats") |
| 101 | ``` |
| 102 | |
| 103 | ## 聚合操作 |
| 104 | |
| 105 | ```javascript |
| 106 | // 基础聚合 |
| 107 | db.orders.aggregate([ |
| 108 | { $match: { status: "completed" } }, |
| 109 | { $group: { _id: "$customer", total: { $sum: "$amount" } } }, |
| 110 | { $sort: { total: -1 } }, |
| 111 | { $limit: 10 } |
| 112 | ]) |
| 113 | |
| 114 | // 常用聚合操作符 |
| 115 | // $match - 过滤 |
| 116 | // $group - 分组 |
| 117 | // $sort - 排序 |
| 118 | // $limit - 限制 |
| 119 | // $skip - 跳过 |
| 120 | // $project - 投影 |
| 121 | // $unwind - 展开数组 |
| 122 | // $lookup - 关联查询 |
| 123 | |
| 124 | // 关联查询 |
| 125 | db.orders.aggregate([ |
| 126 | { |
| 127 | $lookup: { |
| 128 | from: "users", |
| 129 | localField: "userId", |
| 130 | foreignField: "_id", |
| 131 | as: "user" |
| 132 | } |
| 133 | } |
| 134 | ]) |
| 135 | ``` |
| 136 | |
| 137 | ## 备份与恢复 |
| 138 | |
| 139 | ```bash |
| 140 | # 备份数据库 |
| 141 | mongodump --db mydb --out /backup/ |
| 142 | mongodump --uri="mongodb://user:pass@host:27017/mydb" --out /backup/ |
| 143 | |
| 144 | # 备份集合 |
| 145 | mongodump --db mydb --collection users --out /backup/ |
| 146 | |
| 147 | # 压缩备份 |
| 148 | mongodump --db mydb --gzip --archive=/backup/mydb.gz |
| 149 | |
| 150 | # 恢复 |
| 151 | mongorestore --db mydb /backup/mydb/ |
| 152 | mongorestore --uri="mongodb://user:pass@host:27017" /backup/ |
| 153 | |
| 154 | # 恢复压缩备份 |
| 155 | mongorestore --gzip --archive=/backup/mydb.gz |
| 156 | |
| 157 | # 导出 JSON |
| 158 | mongoexport --db mydb --collection users --out users.json |
| 159 | |
| 160 | # 导入 JSON |
| 161 | mongoimport --db mydb --collection users --file users.json |
| 162 | ``` |
| 163 | |
| 164 | ## 副本集管理 |
| 165 | |
| 166 | ```javascript |
| 167 | // 查看副本集状态 |
| 168 | rs.status() |
| 169 | rs.conf() |
| 170 | |
| 171 | // 初始化副本集 |
| 172 | rs.initiate({ |
| 173 | _id: "rs0", |
| 174 | members: [ |
| 175 | { _id: 0, host: "mongo1:27017" }, |
| 176 | { _id: 1, host: "mongo2:27017" }, |
| 177 | { _id: 2, host: "mongo3:27017" } |
| 178 | ] |
| 179 | }) |
| 180 | |
| 181 | // 添加成员 |
| 182 | rs.add("mongo4:27017") |
| 183 | rs.addArb("arbiter:27017") // 添加仲裁节点 |
| 184 | |
| 185 | // 移除成员 |
| 186 | rs.remove("mongo4:27017") |
| 187 | |
| 188 | // 强制主节点切换 |
| 189 | rs.stepDown() |
| 190 | ``` |
| 191 | |
| 192 | ## 性能监控 |
| 193 | |
| 194 | ```javascript |
| 195 | // 服务器状态 |
| 196 | db.serverStatus() |
| 197 | |
| 198 | // 当前操作 |
| 199 | db.currentOp() |
| 200 | db.currentOp({ "active": true, "secs_running": { "$gt": 5 } }) |
| 201 | |
| 202 | // 终止操作 |
| 203 | db.killOp(opid) |
| 204 | |
| 205 | // 慢查询日志 |
| 206 | db.setProfilingLevel(1, { slowms: 100 }) |
| 207 | db.system.profile.find().sort({ ts: -1 }).limit(10) |
| 208 | |
| 209 | // 集合扫描统计 |
| 210 | db.users.stats() |
| 211 | |
| 212 | // 连接数 |
| 213 | db.serverStatus().connections |
| 214 | ``` |
| 215 | |
| 216 | ## 常见场景 |
| 217 | |
| 218 | ### 场景 1:查询优化 |
| 219 | ```javascript |
| 220 | // 分析查询 |
| 221 | db.users.find({ email: "test@example.com" }).explain("executionStats") |
| 222 | |
| 223 | // 检查是否使用索引 |
| 224 | // "stage": "IXSCAN" 表示使用索引 |
| 225 | // "stage": "COLLSCAN" 表示全表扫描 |
| 226 | |
| 227 | // 强制使用索引 |
| 228 | db.users.find({ name: "John" }).hint({ name: 1 }) |
| 229 | ``` |
| 230 | |
| 231 | ### 场景 2:数据迁移 |
| 232 | ```javascript |
| 233 | // 复制集合 |
| 234 | db.source.aggregate([{ $out: "target" }]) |
| 235 | |
| 236 | // 跨数据库复制 |
| 237 | db.source.find().forEach(function(doc) { |
| 238 | db.getSiblingDB("otherdb").target.insert(doc) |
| 239 | }) |
| 240 | ``` |
| 241 | |
| 242 | ### 场景 3:批量更新 |
| 243 | ```javascript |
| 244 | // 批量更新 |
| 245 | db.users.updateMany( |
| 246 | { status: "pending" }, |
| 247 | { $set: { status: "active", updatedAt: new Date() } } |
| 248 | ) |
| 249 | |
| 250 | // 使用 bulkWrite |
| 251 | db.users.bulkWrite([ |
| 252 | { updateOne: { filter: { _id: 1 }, update: { $set: { x: 1 } } } }, |
| 253 | { updateOne: { filter: { _id: 2 }, update: { $set: { x: 2 } } } }, |
| 254 | { deleteOne: { filter: { _id: 3 } } } |
| 255 | ]) |
| 256 | ``` |
| 257 | |
| 258 | ## 故障排查 |
| 259 | |
| 260 | | 问题 | 排查方法 | |
| 261 | |------|----------| |
| 262 | | 查询慢 | `explain()`, 检查索引 | |
| 263 | | 连接数过多 | `db.serverStatus().connections` | |
| 264 | | 内存不足 | 检查 WiredTiger 缓存配置 | |
| 265 | | 副本集同步延迟 | `rs.status()`, 检查 oplog | |
| 266 | | 磁盘空间 | `db.stats()`, compact 操作 | |