标签: MongoDB MySQL Spring Boot 数据迁移 mongoimport MongoDB Compass 日志系统
一、背景与动机
系统操作日志表 sys_log 随着业务增长,在 MySQL 中积累了近 80 万条记录。面临几个痛点:
- 列表查询和模糊检索越来越慢;
- 日志字段(
params、json_result)偏半结构化,关系表约束收益低; - 写入并发上来后,希望降低对业务主库的影响。
MongoDB 的文档模型、索引能力和横向扩展特性非常适合日志/审计类数据。本文记录从 MySQL/CSV → MongoDB 的一次性迁移全过程,包含 Windows 环境下工具链安装、字段映射、高速导入、类型校正、索引重建以及 Spring Boot 对接。
目标库:
kms_logdb目标集合:
sys_log连接方式:用户名/密码,认证库
admin
二、环境准备与工具安装(Windows 重点)
很多同学在执行导入时会遇到:
'mongoimport' 不是内部或外部命令,也不是可运行的程序或批处理文件。
这是因为 MongoDB Server/Compass 默认不携带 mongoimport 。它是独立发布的 MongoDB Database Tools 里的工具。
2.1 安装 MongoDB Database Tools(必须)
下载地址:https://www.mongodb.com/try/download/database-tools
选择 Windows / MSI 安装包,一路下一步。默认路径类似:
C:\Program Files\MongoDB\Tools\100\bin\
里面包含:
mongoimport.exe
mongodump.exe
mongorestore.exe
mongostat.exe
...
2.2 配置系统环境变量 PATH
-
控制面板 → 系统 → 高级系统设置 → 环境变量
-
系统变量中找到
Path→ 编辑 → 新建 -
填入:
C:\Program Files\MongoDB\Tools\100\bin\
-
确定保存,重新打开 CMD/PowerShell
-
验证:
mongoimport --version
能输出版本号即成功。
如果不想配置环境变量,后面所有命令都要写完整路径,例如:
"C:\Program Files\MongoDB\Tools\100\bin\mongoimport.exe" ...
2.3 MongoDB Compass(可选,但强烈推荐)
用于可视化连接、查看数据、校验字段、建索引和抽样调试。你如果已经连上 10.11.254.56:27017 和 localhost:27017,就可以用它做后期校验。
注意:Compass 可以导入小批量 CSV,但 80w 数据不建议用它导,容易卡顿/超时,主力仍是
mongoimport。
三、源数据准备:CSV 表头与字段映射
假设从 MySQL 或 Excel 拿到的原始 CSV 表头是:
id,username,operation,method,params,json_result,time,ip,create_date
MongoDB/Spring Boot 实体我们期望:
@Document(collection = "sys_log")
public class SysLogEntity {
@Id
private String id; // MongoDB 自动生成 _id
private String username;
private String operation;
private String method;
private String params;
private String jsonResult; // 不是 json_result
private Long time;
private String ip;
private Date createDate; // 不是 create_date
}
所以 CSV 最终表头必须改为:
username,operation,method,params,jsonResult,time,ip,createDate
操作步骤:
-
删除
id列(让 MongoDB 自动生成_id) -
json_result→jsonResult -
create_date→createDate -
保存为标准 CSV(推荐 UTF-8,逗号分隔)
-
文件路径:
C:\Users\Lenovo\Desktop\sys_log.csv
日期格式尽量是:
2025-02-07 15:55:32
如果是 Excel 导出的 2/7/2025 15:55:32,后面用 $dateFromString 处理。
四、MongoDB 侧初始化集合与校验规则
用 mongosh 或 Compass 的 Shell/查询窗口执行:
db = db.getSiblingDB('kms_logdb');
var SYS_LOG_VALIDATOR = {
$jsonSchema: {
bsonType: "object",
required: ["_id", "username", "operation", "method", "params", "jsonResult", "time", "ip", "createDate"],
properties: {
_id: { bsonType: "objectId" },
username: { bsonType: "string" },
operation: { bsonType: "string" },
method: { bsonType: "string" },
params: { bsonType: "string" },
jsonResult: { bsonType: "string" },
time: { bsonType: ["long", "int"] },
ip: { bsonType: "string" },
createDate: { bsonType: "date" }
}
}
};
if (db.getCollectionNames().indexOf('sys_log') < 0) {
db.createCollection('sys_log', {
validator: SYS_LOG_VALIDATOR,
validationLevel: "moderate",
validationAction: "warn"
});
} else {
db.runCommand({
collMod: "sys_log",
validator: SYS_LOG_VALIDATOR,
validationLevel: "moderate",
validationAction: "warn"
});
}
print('✅ 集合初始化完成:kms_logdb.sys_log');
validationLevel: "moderate" + validationAction: "warn" 表示已有文档不强制打断,只告警,适合迁移场景。
五、导入前:删除旧索引,提升写入速度
80w 数据导入时,如果已有索引会大幅拖慢写入。
db.sys_log.dropIndexes();
六、使用 mongoimport 高速导入
CMD 中执行(已配 PATH 的写法):
mongoimport ^
--host=127.0.0.1 ^
--port=27017 ^
--username=root ^
--password=test ^
--authenticationDatabase=admin ^
--db=kms_logdb ^
--collection=sys_log ^
--type=csv ^
--headerline ^
--file="C:\Users\Lenovo\Desktop\sys_log.csv" ^
--numInsertionWorkers=4 ^
--batchSize=5000
如果没配 PATH,用:
"C:\Program Files\MongoDB\Tools\100\bin\mongoimport.exe" ^
--host=127.0.0.1 ^
--port=27017 ^
--username=root ^
--password=test ^
--authenticationDatabase=admin ^
--db=kms_logdb ^
--collection=sys_log ^
--type=csv ^
--headerline ^
--file="C:\Users\Lenovo\Desktop\sys_log.csv" ^
--numInsertionWorkers=4 ^
--batchSize=5000
参数说明:
--headerline:使用 CSV 第一行作为字段名--numInsertionWorkers=4:并发写入,提升吞吐--batchSize=5000:每批写入量- 密码含
@,用参数方式传,不要拼 URI,避免解析错误
七、导入后类型校正(非常关键)
CSV 导入后,数字和日期往往会被当成字符串/int,需要校正。
7.1 time 统一为 long
db.sys_log.updateMany(
{ time: { $type: "int" } },
[{ $set: { time: { $toLong: "$time" } } }]
);
7.2 createDate 转 Date
如果是 2025-02-07 15:55:32:
db.sys_log.updateMany(
{ createDate: { $type: "string" } },
[{ $set: { createDate: { $toDate: "$createDate" } } }]
);
如果是 2/7/2025 15:55:32:
db.sys_log.updateMany(
{ createDate: { $type: "string" } },
[{
$set: {
createDate: {
$dateFromString: {
dateString: "$createDate",
format: "%d/%m/%Y %H:%M:%S"
}
}
}
}]
);
八、重建索引
对齐原 MySQL 查询习惯:
db.sys_log.createIndex({ createDate: -1 }, { name: 'idx_create_date' });
db.sys_log.createIndex({ operation: 1 }, { name: 'idx_operation' });
db.sys_log.createIndex({ username: 1 }, { name: 'idx_username' });
db.sys_log.createIndex({ username: 1, operation: 1 }, { name: 'idx_username_operation' });
db.sys_log.createIndex({ createDate: -1, _id: -1 }, { name: 'idx_create_date_id' });
如果日志只需保留 90 天,可加 TTL(可选):
db.sys_log.createIndex(
{ createDate: 1 },
{ name: 'ttl_create_date', expireAfterSeconds: 90 * 24 * 3600 }
);
九、数据校验
db.sys_log.countDocuments()
db.sys_log.findOne()
db.sys_log.aggregate([
{ $sample: { size: 10 } },
{
$project: {
timeType: { $type: "$time" },
dateType: { $type: "$createDate" },
username: 1,
operation: 1,
createDate: 1
}
}
]);
期望:
countDocuments()≈ MySQL 的SELECT COUNT(*)timeType→longdateType→date
在 Compass 里也可以直接打开 kms_logdb.sys_log 看文档结构和索引。
十、Spring Boot 配置对接
spring:
data:
mongodb:
authentication-database: admin
host: 127.0.0.1
port: 27017
username: root
password: test
database: kms_logdb
实体类:
@Document(collection = "sys_log")
public class SysLogEntity {
@Id
private String id;
private String username;
private String operation;
private String method;
private String params;
private String jsonResult;
private Long time;
private String ip;
private Date createDate;
// getter / setter
}
Repository:
public interface SysLogRepository extends MongoRepository<SysLogEntity, String> {
Page<SysLogEntity> findByUsernameContainingOrOperationContaining(
String username, String operation, Pageable pageable);
}
字段名与 CSV/MongoDB 完全一致,无需额外映射。
十一、常见问题与坑
1. mongoimport 不是命令
安装 MongoDB Database Tools 并配 PATH,或用完整 exe 路径。
2. 密码含特殊字符(如 @)
用 --password=xxx 参数形式,不要拼连接字符串 URI。
3. 日期导入后是字符串
导入后用 $toDate 或 $dateFromString 校正。
4. 字段名下划线/驼峰不一致
MySQL: json_result, create_date
MongoDB/Java: jsonResult, createDate
CSV 表头必须提前改好。
5. 导入慢
先 dropIndexes(),再用 --numInsertionWorkers 和 --batchSize。
6. Compass 能导入吗?
能,但适合小数据/校验。80w 条请用 mongoimport。
十二、总结
完整链路:
MySQL/Excel CSV 准备表头
↓
安装 mongoimport / Compass 连接校验
↓
mongosh 初始化 sys_log + validator
↓
dropIndexes()
↓
mongoimport 导入 80w
↓
校正 time / createDate 类型
↓
重建索引
↓
Spring Boot 对接 kms_logdb
迁移后日志查询和写入性能明显提升,MongoDB 的文档结构也更贴合日志这类半结构化数据。
后续可扩展:
- TTL 自动清理历史日志
- 异步批量写入
- MySQL/MongoDB 双写平滑切换
- 按时间分片/归档
希望这篇能帮你少踩 Windows 工具链和字段映射的坑。