业务数据是 JSON 结构、字段经常变?用户量大了想横向扩展?用 MySQL 改表结构改到崩溃?MongoDB 是非关系型数据库(NoSQL)里最流行的:数据以文档(类似 JSON)形式存储,字段随意增删、结构灵活,天生支持水平扩展,是日志、用户信息、商品数据等场景的常客。这篇文章带你从零安装 MongoDB,并掌握最常用的操作。
一、MongoDB 是什么?和 MySQL 有什么区别
MySQL 存的是"表 + 行 + 列",结构固定,改结构要 ALTER TABLE;MongoDB 存的是"集合 + 文档",文档就是 JSON 对象,每条文档的字段可以不一样。
| 对比 | MySQL | MongoDB |
|---|---|---|
| 数据单位 | 表 / 行 | 集合(collection)/ 文档(document) |
| 数据结构 | 固定列,需预先设计 | 灵活,字段随意增删 |
| 查询语言 | SQL | 类 JSON 查询 |
| 扩展方式 | 主从、分库分表 | 原生分片(sharding) |
| 适合场景 | 事务要求高、强结构 | 数据结构灵活、高并发读写 |
二、安装 MongoDB
Ubuntu/Debian 安装(官方源):
# 导入官方 GPG 密钥
curl -fsSL https://pgp.mongodb.com/server-7.0.asc | gpg --dearmor -o /usr/share/keyrings/mongodb-server-7.0.gpg
# 添加软件源
echo "deb [ signed-by=/usr/share/keyrings/mongodb-server-7.0.gpg ] http://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/7.0 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-7.0.list
apt update && apt install -y mongodb-org
CentOS 7 安装:
cat > /etc/yum.repos.d/mongodb-org-7.0.repo <<'EOF'
[mongodb-org-7.0]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/7.0/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://pgp.mongodb.com/server-7.0.asc
EOF
yum install -y mongodb-org
启动并设为开机自启:
systemctl start mongod
systemctl enable mongod
systemctl status mongod # 确认 running
连接测试:
mongosh # MongoDB 7.0 的客户端命令是 mongosh(旧版是 mongo)
三、数据库与集合的基本操作
进入 mongosh 后,先理解三个层级:数据库(database)-> 集合(collection)-> 文档(document)。
查看与切换数据库:
show dbs // 查看所有数据库
use blog // 切换/创建数据库(MongoDB 是惰性创建,插入数据才真正建库)
db // 查看当前所在数据库
创建集合(collection):
MongoDB 不需要显式建集合,插入文档时集合会自动创建。也可以手动建:
db.createCollection("users")
show collections // 查看当前库所有集合
四、增删改查(CRUD)
1. 插入文档
// 插入单条
db.users.insertOne({
username: "zhangsan",
email: "zs@example.com",
age: 25,
tags: ["vip", "tech"]
})
// 插入多条
db.users.insertMany([
{ username: "lisi", email: "ls@example.com", age: 30 },
{ username: "wangwu", age: 22 } // 字段可以不一样!
])
2. 查询文档
// 查询所有
db.users.find()
// 按条件查询
db.users.find({ username: "zhangsan" })
db.users.find({ age: { $gt: 24 } }) // age > 24
db.users.find({ tags: "vip" }) // 数组包含 vip
// 只返回指定字段(1 显示,0 隐藏)
db.users.find({}, { username: 1, email: 1, _id: 0 })
// 限制条数并排序
db.users.find().sort({ age: -1 }).limit(10) // 按 age 倒序前 10 条
// 计数
db.users.countDocuments({ age: { $gt: 24 } })
3. 更新文档
// 更新第一条匹配的文档($set 只更新指定字段)
db.users.updateOne(
{ username: "zhangsan" },
{ $set: { email: "new@example.com", age: 26 } }
)
// 更新所有匹配的文档
db.users.updateMany(
{ tags: "vip" },
{ $set: { level: "gold" } }
)
4. 删除文档
db.users.deleteOne({ username: "wangwu" }) // 删除第一条匹配
db.users.deleteMany({ age: { $lt: 20 } }) // 删除所有 age<20
db.users.drop() // 删除整个集合
五、索引:查询提速的关键
数据量大后,不加索引的查询是"全表扫描",慢得离谱。给高频查询字段建索引:
// 单字段索引
db.users.createIndex({ username: 1 }) // 1 升序,-1 降序
// 复合索引(多条件查询)
db.users.createIndex({ age: 1, username: 1 })
// 唯一索引(字段值不能重复)
db.users.createIndex({ email: 1 }, { unique: true })
// 查看索引
db.users.getIndexes()
用 explain 检查查询是否走了索引:
db.users.find({ username: "zhangsan" }).explain("executionStats")
// executionStats.totalDocsExamined 远大于返回条数,说明没走索引
六、备份与恢复
备份(mongodump):
# 备份整个库
mongodump --db blog --out /backup/mongo/
# 带认证备份
mongodump -u admin -p '密码' --authenticationDatabase admin --db blog --out /backup/mongo/
恢复(mongorestore):
mongorestore --db blog /backup/mongo/blog/
补充:还有更高级的 mongodump 归档格式(适合大数据量):
mongodump --db blog --archive=/backup/blog.archive
mongorestore --archive=/backup/blog.archive
配合 crontab 就能做定时备份:
0 2 * * * mongodump --db blog --out /backup/mongo/$(date +\%Y\%m\%d) >> /var/log/mongo-backup.log 2>&1
七、开启认证与远程连接
默认 MongoDB 无密码且只监听 127.0.0.1。上生产环境必须开认证。
第 1 步:创建管理员用户
use admin
db.createUser({
user: "admin",
pwd: "强密码",
roles: [{ role: "root", db: "admin" }]
})
第 2 步:修改配置开启认证
编辑 /etc/mongod.conf:
security:
authorization: enabled
重启:
systemctl restart mongod
第 3 步:带认证连接
mongosh -u admin -p '密码' --authenticationDatabase admin
第 4 步:允许远程连接(可选,谨慎)
修改 /etc/mongod.conf 监听地址:
net:
port: 27017
bindIp: 0.0.0.0
⚠️ 开启远程后务必:开认证、改默认端口(或不用默认 27017)、用防火墙只放行你的 IP,否则分分钟被扫库勒索。
防火墙放行示例(仅限你的 IP):
firewall-cmd --permanent --add-rich-rule='rule family=ipv4 source address=1.2.3.4 port protocol=tcp port=27017 accept'
firewall-cmd --reload
八、常见问题排查
1. 启动失败:Job for mongod.service failed
先看日志:
journalctl -u mongod -n 50
常见原因:磁盘满、/var/lib/mongo 权限不对(chown -R mongod:mongod /var/lib/mongo)。
2. 连接被拒绝:connect ECONNREFUSED
服务没起来或监听地址不对。确认 systemctl status mongod 是 running,netstat -tlnp | grep 27017 有监听。
3. 认证失败:Authentication failed
用户是在哪个库创建的,连接时 --authenticationDatabase 就要指向那个库(admin 用户指向 admin)。
4. 查询慢
先检查有没有索引(getIndexes),没有就给高频字段建索引。
总结
MongoDB 上手很快:文档就是 JSON,insertOne / find / updateOne / deleteOne 四件套走天下;数据量大了记得建索引;生产环境第一件事是开认证;备份用 mongodump + cron 定时执行。它和 MySQL 不是替代关系,而是各有擅场——结构灵活、高并发读写的场景,MongoDB 会是更好的选择。




