平时做技术实践时,很多问题不是概念不会,而是细节没串起来。拿“MongoDB导出和导入实用指南(含详细代码)”来说,它看着像小点,放到项目里常会牵出环境、配置、兼容性和维护成本。下面按实际采用顺序,把思路、关键写法和容易踩坑的地方讲清楚,便于大家直接对照操作。
数据导出 (Export)
1.mongodump (二进制备份)
# 基本用法 - 导出整个数据库
mongodump --db=mydatabase --out=/backup/path
# 导出特定集合
mongodump --db=mydatabase --collection=users --out=./backup
# 带认证导出
mongodump --host localhost --port 27017
--username admin --password "password"
--authenticationDatabase admin
--db mydatabase
--out=./backup
# 压缩导出(推荐用于大数据库)
mongodump --uri="mongodb://localhost:27017/mydatabase"
--gzip
--out=./backup_compressed
# 导出所有数据库
mongodump --uri="mongodb://localhost:27017"
--out=./full_backup
# 导出时排除某些集合
mongodump --db=mydatabase
--excludeCollection=sessions
--excludeCollection=logs
--out=./backup
# 导出查询结果
mongodump --db=mydatabase
--collection=orders
--query='{"status": "completed", "date": {"$gt": {"$date": "2024-01-01T00:00:00Z"}}}'
--out=./backup
2.mongoexport (JSON/CSV格式)
# 导出为JSON
mongoexport --db=mydatabase --collection=users --out=users.json
# 导出为CSV
mongoexport --db=mydatabase --collection=users
--type=csv
--fields=name,email,age,created_at
--out=users.csv
# 带查询条件导出
mongoexport --db=mydatabase --collection=products
--query='{"price": {"$gt": 100}, "inStock": true}'
--out=expensive_products.json
# 导出特定字段
mongoexport --db=mydatabase --collection=users
--fields=_id,name,email
--out=users_basic.json
# 导出漂亮格式的JSON
mongoexport --db=mydatabase --collection=users
--pretty
--out=users_pretty.json
# 导出到标准输出
mongoexport --db=mydatabase --collection=users | gzip > users.json.gz
数据导入 (Import)
1.mongorestore (恢复二进制备份)
# 恢复整个数据库
mongorestore --db=mydatabase ./backup/mydatabase/
# 恢复特定集合
mongorestore --db=mydatabase
--collection=users
./backup/mydatabase/users.bson
# 恢复压缩备份
mongorestore --gzip --db=mydatabase ./backup_compressed/mydatabase/
# 恢复时保留原数据(默认会删除现有数据)
mongorestore --db=mydatabase --drop ./backup/mydatabase/
# 恢复时重命名数据库
mongorestore --db=newdatabase ./backup/mydatabase/
# 恢复单个集合
mongorestore --db=mydatabase
--nsFrom="olddb.users"
--nsTo="mydatabase.users"
./backup/olddb/users.bson
# 并行恢复(加速大数据库恢复)
mongorestore --numParallelCollections=4
--db=mydatabase
./backup/mydatabase/
2.mongoimport (导入JSON/CSV)
# 导入JSON文件
mongoimport --db=mydatabase --collection=users --file=users.json
# 导入CSV文件
mongoimport --db=mydatabase --collection=users
--type=csv
--headerline
--file=users.csv
# 导入时指定字段
mongoimport --db=mydatabase --collection=users
--type=csv
--fields=name,email,age
--file=users.csv
# 导入并删除原有数据
mongoimport --db=mydatabase --collection=users
--drop
--file=users.json
# 导入时忽略重复键错误
mongoimport --db=mydatabase --collection=users
--stopOnError
--file=users.json
# 分批导入
mongoimport --db=mydatabase --collection=users
--batchSize=1000
--numInsertionWorkers=4
--file=users.json
# 导入时处理日期格式
mongoimport --db=mydatabase --collection=logs
--columnsHaveTypes
--fields="timestamp.date(2006-01-02 15:04:05),message.string()"
--file=logs.csv
完整导出导入流程示例
场景1:迁移数据库到新服务器
# 1. 在源服务器导出
mongodump --uri="mongodb://source:27017/production"
--gzip
--out=./mongobackup
# 2. 压缩备份文件
tar -czf mongobackup.tar.gz mongobackup/
# 3. 传输到目标服务器
scp mongobackup.tar.gz user@target-server:/tmp/
# 4. 在目标服务器恢复
tar -xzf /tmp/mongobackup.tar.gz
mongorestore --uri="mongodb://target:27017/production"
--gzip
./mongobackup/production/
场景2:导出为CSV,修改后导入
# 1. 导出为CSV
mongoexport --db=sales --collection=orders
--type=csv
--fields=order_id,customer,amount,date
--out=orders.csv
# 2. 使用Excel或脚本修改CSV文件
# ... 修改数据 ...
# 3. 导入修改后的数据
mongoimport --db=sales --collection=orders_modified
--type=csv
--headerline
--file=orders_modified.csv
场景3:备份和恢复特定时间点的数据
# 创建带时间戳的备份
BACKUP_DIR="/backups/mongodb/$(date +%Y%m%d_%H%M%S)"
mongodump --db=importantdb --out="$BACKUP_DIR"
# 列出所有备份
ls -la /backups/mongodb/
# 恢复到特定备份
mongorestore --db=importantdb
"/backups/mongodb/20240115_143022/importantdb"
性能优化技巧
导出优化
# 并行导出多个集合
mongodump --db=largedb
--numParallelCollections=8
--out=./backup
# 使用更快的压缩
mongodump --db=largedb
--gzip
--archive=backup.gz
--quiet # 减少日志输出
导入优化
# 禁用索引构建(导入后再创建)
mongorestore --db=largedb
--noIndexRestore
./backup/largedb/
# 之后手动创建索引
mongosh --eval "db.getSiblingDB('largedb').getCollection('users').createIndex({email: 1})"
# 批量插入优化
mongoimport --db=largedb --collection=users
--batchSize=10000
--numInsertionWorkers=8
--file=users.json
安全注意事项
# 使用SSL连接
mongodump --uri="mongodb+srv://username:[email protected]/db"
--ssl
--out=./backup
# 从配置文件读取凭证(避免密码暴露在命令行)
# 创建配置文件 backup.conf
echo '
uri = mongodb://admin:password@localhost:27017
ssl = true
authenticationDatabase = admin
' > backup.conf
mongodump --config=backup.conf --out=./backup
导出导入统计信息
# 导出前查看数据大小
mongosh --eval "
db = db.getSiblingDB('mydatabase');
const stats = db.stats();
print('Database size:', stats.dataSize);
print('Collections:', stats.collections);
"
# 导入后验证数据
mongosh --eval "
db = db.getSiblingDB('mydatabase');
print('Total documents:', db.users.countDocuments());
print('Sample document:', JSON.stringify(db.users.findOne()));
"
常用问题解决
问题1:ObjectId 转换错误
# 导出时转换ObjectId为字符串
mongoexport --db=mydb --collection=users
--jsonFormat=canonical
--out=users.json
# 或使用--legacy格式
mongoexport --db=mydb --collection=users
--legacy
--out=users.json
问题2:大文件导入导出
# 分片导出大集合
mongodump --db=mydb --collection=huge_collection
--query='{"_id": {"$lt": ObjectId("65a1b2c3d4e5f67890123456")}}'
--out=./part1
# 使用split分割文件
mongoexport --db=mydb --collection=users
--out=users.json
split -l 100000 users.json users_part_
# 并行导入分片文件
for file in users_part_*; do
mongoimport --db=mydb --collection=users --file="$file" &
done
wait
问题3:版本兼容性
# 导出时指定兼容版本
mongodump --db=mydb
--compatibilityVersion=4.4
--out=./backup
# 查看工具版本
mongodump --version
mongorestore --version
最佳实践
- 始终在非高峰时段执行大规模导出导入
- 先导出到本地磁盘,再传输到目标
- 验证导出完整性:检查文档数量和文件大小
- 测试恢复流程:定期演练恢复过程
- 采用–gzip压缩:减少传输时间和存储空间
- 记录操作日志:保存所有导出导入命令
- 监控性能影响:采用mongostat监控服务器负载
更快参考表
| 操作 | 命令 | 用途 |
|---|---|---|
| 导出整个DB | mongodump --db=mydb --out=./backup | 二进制备份 |
| 导出为JSON | mongoexport --db=mydb --collection=users --out=users.json | 可读格式 |
| 导出为CSV | mongoexport --db=mydb --collection=users --type=csv --fields=name,email | 表格格式 |
| 恢复DB | mongorestore --db=mydb ./backup/mydb/ | 从备份恢复 |
| 导入JSON | mongoimport --db=mydb --collection=users --file=users.json | 导入JSON |
| 导入CSV | mongoimport --db=mydb --collection=users --type=csv --headerline | 导入CSV |
| 压缩导出 | mongodump --gzip --db=mydb --out=./backup | 节省空间 |
| 并行操作 | --numParallelCollections=4 | 提高速度 |
实际处理时,这个指南涵盖了大多数导出导入场景,根据你的具体需求选择合适的工具和参数即可。
mongorestore --db=hsrg ./backup导入错误分析
当你采用 mongodump 备份时,它会新建以下结构:
./backup/
└── hsrg/ # 数据库文件夹
├── collection1.bson
├── collection1.metadata.json
└── collection2.bson
但你的 mongorestore 命令指向的是 ./backup 目录,而不是 ./backup/hsrg。
解决方案
方案1:指定正确的路径
# 正确写法(指定到数据库文件夹)
mongorestore --db=hsrg ./backup/hsrg/
# 或者
mongorestore ./backup/hsrg/
方案2:采用新语法(建议)
# 使用新的 --nsInclude 语法
mongorestore --nsInclude="hsrg.*" ./backup/
# 或者恢复整个备份目录中的所有数据库
mongorestore ./backup/
正确的完整流程示例
导出时:
# 导出 hsrg 数据库
mongodump --db=hsrg --out=./backup
# 查看导出结果
ls -la ./backup/
# 应该能看到 hsrg 目录
导入时:
# 方法1:直接恢复整个备份目录
mongorestore ./backup/
# 方法2:只恢复 hsrg 数据库到新数据库名
mongorestore --nsFrom="hsrg.*" --nsTo="newhsrg.*" ./backup/
# 方法3:使用新语法
mongorestore --nsInclude="hsrg.*" ./backup/
如果你需覆盖现有数据:
# 先删除现有数据再恢复
mongorestore --drop --db=hsrg ./backup/hsrg/
验证备份结构
# 先查看备份目录结构
tree ./backup/
# 或者
ls -R ./backup/
# 示例输出应该类似于:
# ./backup/
# └── hsrg
# ├── users.bson
# ├── users.metadata.json
# ├── products.bson
# └── products.metadata.json
常用错误及解决
错误1:备份文件在错误的位置
# 如果备份文件直接在 backup 目录下,而不是 backup/hsrg 下
# 需要调整目录结构
mkdir -p ./backup/hsrg
mv ./backup/*.bson ./backup/*.metadata.json ./backup/hsrg/ 2>/dev/null || true
mongorestore ./backup/
错误2:权限问题
# 检查文件权限
ls -la ./backup/hsrg/
# 如果有权限问题
chmod -R 755 ./backup/
错误3:版本不兼容
# 检查 MongoDB 版本
mongorestore --version
mongodump --version
# 如果版本不匹配,使用兼容模式
mongorestore --db=hsrg ./backup/hsrg/ --noIndexRestore
一键修复脚本
#!/bin/bash
# fix_mongorestore.sh
BACKUP_DIR="./backup"
DB_NAME="hsrg"
# 检查备份目录是否存在
if [ ! -d "$BACKUP_DIR" ]; then
echo "错误:备份目录 $BACKUP_DIR 不存在"
exit 1
fi
# 检查数据库目录是否存在
if [ -d "$BACKUP_DIR/$DB_NAME" ]; then
echo "检测到正确的目录结构,开始恢复..."
mongorestore --db="$DB_NAME" "$BACKUP_DIR/$DB_NAME/"
elif [ -f "$BACKUP_DIR/$DB_NAME.bson" ]; then
echo "检测到旧格式备份,调整目录结构..."
mkdir -p "$BACKUP_DIR/$DB_NAME"
mv "$BACKUP_DIR/$DB_NAME".* "$BACKUP_DIR/$DB_NAME/" 2>/dev/null
mongorestore --db="$DB_NAME" "$BACKUP_DIR/$DB_NAME/"
else
echo "错误:无法识别的备份结构"
echo "目录内容:"
ls -la "$BACKUP_DIR"
exit 1
fi
总结
你的问题是因为:
- 备份目录结构不对
mongorestore路径指定错误
正确的命令应该是:
# 先查看备份目录内容
ls -la ./backup/
# 如果看到 hsrg 目录
mongorestore --db=hsrg ./backup/hsrg/
# 或者直接用新语法
mongorestore ./backup/
全文总结
# 导出
mongodump --db=hsrg --out=./backup
#导入
mongorestore --db=hsrg ./backup/hsrg/
## 重点
为什么导入的路径多个hsrg,是因为导出的时候携带有表名称
从实现思路看,总的来说,mongodb导出整个数据库适合结合实际项目边做边理解。先抓住核心思路,再逐步补上细节和边界处理,最后效果会更稳定,也更容易复用。