当前位置: 首页 > news >正文

MongoDB 大数据备份,新手教程

在 MongoDB 中,将数据复制到备份集合(归档集合)方案有很多种,操作流程与示例演示

1、方案介绍

方案一:$merge(最推荐,原子操作)

$merge是 MongoDB 4.2+ 引入的特性,可以将聚合管道的结果写入指定的集合。当目标集合和源集合在同一个数据库时,这是性能最高的方式,因为它完全在数据库引擎内部完成。

目标:将sales集合中 2024 年的所有文档复制到sales_archive_2024集合。

use your_database; // 1. 执行复制操作 db.sales.aggregate([ { $match: { create_time: { $gte: ISODate("2024-01-01T00:00:00Z"), $lt: ISODate("2025-01-01T00:00:00Z") } } }, { $merge: { into: "sales_archive_2024", // 目标集合名 on: "_id", // 基于_id去重(防止重复插入) whenMatched: "replace", // 如果_id已存在则覆盖 whenNotMatched: "insert" // 如果不存在则插入 } } ]);

参数详解

  • on: "_id":指定用_id字段来判断文档是否已存在,这是防止意外重复执行导致数据翻倍的关键。

  • whenMatched: "replace":如果目标集合中已存在相同_id的文档,就用新文档覆盖它。这保证了操作的幂等性,你可以安全地多次执行。

  • whenNotMatched: "insert":如果不存在,则正常插入。

验证:执行后,你可以通过以下命令快速确认复制的数据量是否一致。

// 统计源集合中2024年的文档数 db.sales.countDocuments({ create_time: { $gte: ISODate("2024-01-01T00:00:00Z"), $lt: ISODate("2025-01-01T00:00:00Z") } }); // 统计归档集合中的文档数 db.sales_archive_2024.countDocuments();

方案二:find()+insertMany()(适合较旧版本或小批量数据)

方案三:bulkWrite分批处理(处理大数据集的安全方式)

如果数据量巨大(千万级以上),且因某些原因不能使用$merge,用bulkWrite结合skip/limit进行分批复制是最安全的。

const batchSize = 5000; let processed = 0; let hasMore = true; while (hasMore) { // 每次从源表取5000条 const batch = db.sales.find({ create_time: { $gte: ISODate("2024-01-01T00:00:00Z"), $lt: ISODate("2025-01-01T00:00:00Z") } }).skip(processed).limit(batchSize).toArray(); if (batch.length === 0) { hasMore = false; break; } // 构建批量插入操作 const operations = batch.map(doc => ({ insertOne: { document: doc } })); db.sales_archive_2024.bulkWrite(operations, { ordered: false }); processed += batch.length; print(`已复制 ${processed} 条文档...`); }

2、复制后的清理与空间回收

完成复制并验证数据完整性后,就可以安全地删除源数据了。

2.1 删除源数据(分批进行):

// 同样,建议分批删除,避免大事务 const sixMonthsAgo = new Date(); sixMonthsAgo.setMonth(sixMonthsAgo.getMonth() - 6); while (db.sales.find({ create_time: { $lt: sixMonthsAgo } }).count() > 0) { db.sales.deleteMany({ create_time: { $lt: sixMonthsAgo } }, { limit: 5000 }); sleep(100); // 每批暂停100ms }

2.2 回收磁盘空间(维护窗口执行):
删除操作后,MongoDB 的磁盘空间不会自动释放。你需要执行压缩:

// 在主节点执行会阻塞读写,建议在从节点执行或安排维护时间 db.runCommand({ compact: "sales" });

3、演示示例

3.1 MongoDB控制台操作

1、连接操作台: mongosh "mongodb://localhost:27017" 2、显示数据库: show databases 3、切换到指定数据库(如果不存在则创建): use <database_name> 4、查看当前所使用的数据库: db 5、显示当前数据库中的所有集合: show collections

3.2 复制集合操作如下命令

db.t_order_package.aggregate([ { $match: { date: { $gte: "2025-01-01", $lte: "2025-12-31" } //日期大于等于“2025-01-01”,小于等于“2025-12-31” } }, { $merge: { into: "t_order_package_2025",// 目标集合名 on: "_id",// 基于_id去重(防止重复插入) whenMatched: "replace",// 如果_id已存在则覆盖 whenNotMatched: "insert"// 如果不存在则插入 } } ]);

这样操作后,会将集合“t_order_package”按照条件复制内容到“t_order_package_2025”集合里

注:几百万的数据量也是可以直接复制的

3.3 验证数据集

//按指南条件查询原数据集的数据量 db.t_order_package.countDocuments({ date: { $gte: "2025-01-01", $lte: "2025-12-31" } }); // 统计归档集合数据量 db.t_order_package_2025.countDocuments(); //若他们数据量相等,说明复制正确

3.4 删除原数据集的数据

//尽量分批操作 db.t_order_package.deleteMany({date:{$lte:"2024-12-31"}}); //指定条件查询原数据集的数据量 db.runCommand({compact:"t_order_package"});

3.5 回收磁盘空间

db.runCommand({compact:"t_order_package"}); //这类似mysql的OPTIMIZE操作

4、MongoDB常用的比较操作符

常用操作符

操作符含义类比 SQL
$gt于 (Greater Than)>
$gte大于等于(Greater Than or Equal)>=
$lt于 (Less Than)<
$lte小于等于(Less Than or Equal)<=
$eq等于(Equal)=
$ne不等于(Not Equal)!=
$in在...之中(In)IN
$nin不在...之中(Not In)NOT IN

示例

// 1. 查询 2024-01-01 之后的数据(不含当天) db.orders.find({ date: { $gt: "2024-01-01" } }); // 2. 查询 2024-01-01 及之后的数据(含当天) db.orders.find({ date: { $gte: "2024-01-01" } }); // 3. 查询 2024-12-31 之前的数据(不含当天) db.orders.find({ date: { $lt: "2024-12-31" } }); // 4. 查询 2024-01-01 到 2024-12-31 之间(含首尾) db.orders.find({ date: { $gte: "2024-01-01", $lte: "2024-12-31" } }); // 5. 查询 status 不等于 0 的数据 db.orders.find({ status: { $ne: 0 } }); // 6. 查询 status 为 0 或 1 的数据 db.orders.find({ status: { $in: [0, 1] } });

字符串日期比较的注意事项

因为你的date字段是字符串类型(如"2025-04-05"),字符串比较是按字典序(逐字符比较)进行的。

// ✅ 正确:因为 "2024-01-01" < "2024-12-31" (逐位比较) "2024-01-01" < "2024-12-31" // true // ✅ 正确:月份和日期是两位数,比较没问题 "2024-01-01" < "2024-01-02" // true // ❌ 错误:如果月份不是两位数,比较会出错 "2024-1-1" < "2024-01-01" // false(因为 '1' > '0')

所以你的数据格式"2025-04-05"$gte/$lte是完全安全的。

快速记忆

GreaterThan =GT→ 大于
LessThan =LT→ 小于
加上E=Equal → 加上等于

所以:

  • $gte= 大于等于

  • $lte= 小于等于

5、总结

维护时,尽量在服务器空闲时操作,操作时要细心,注意做好备份。备份数据还可以使用mongoexport/mongoimport工具链

http://www.jsqmd.com/news/1125696/

相关文章:

  • Git脏树(Dirty Tree)介绍(指工作目录中存在未提交修改的状态)已修改、未跟踪、git status、线上线下不一致问题
  • Gateway API:Ingress 的下一代替代方案
  • UE4 SceneCaptureComponent2D 实战:3步实现UI内3D模型360°预览(附蓝图)
  • 教育学论文降AI工具免费推荐:2026年教育学毕业论文AIGC超标4.8元亲测99.26%知网完整方案
  • CodaYun 一站式浏览器工作台:开发者 设计师专属效率解决方案
  • C++中的String的常用函数用法
  • 【算法从零到千】【32-41】位运算(详细讲解+题目运用)
  • Allegro 生产文件导出:Gerber 274X 与钻孔文件 5 步标准化检查清单
  • 羽球联盟 HarmonyOS NEXT 实战系列 (03/20):四Tab首页容器与资讯首屏搭建
  • Agentic AI:换个角度,从问题拆解到交付验证
  • 史上最简单!sirpdboy固件一键搞定软路由刷机、调试、扩容,彻底告别麻烦!
  • 多模态大模型架构的收敛与分化:从Transformer到模态定制
  • 全局光照/阴影的几个常见问题
  • Linux指令实战学习之内存泄漏
  • 堪萨斯大学新研究:揭示读唇出错原因,有望提升读唇训练与AI转录能力
  • 小模型回到电脑本地,数据安全就自动解决了吗?
  • 1D-CNN 轴承故障诊断实战:CWRU 数据集 6 类识别准确率达 99.2%
  • 小米寥寥几家车企设计汽车顶棚
  • 数智驱动 全域增长:劲捷KINGJOY的跨界突围与全域增长之路
  • 一颗Codec芯片的生存法则:为什么AI语音产品需要TP9311?
  • Agent 需要拦截模型调用?用 Middleware 给它加个“拦截器“!
  • 图像哈希算法(aHash/dHash/pHash)Python实战:3种方法对比与汉明距离阈值调优指南
  • 2026真太阳时八字排盘工具怎么选:看出生地校正、时区口径和隐私边界
  • HLS Downloader:浏览器里直接抓取和下载直播流
  • QT 5升级到 Qt 6 使用 Clazy 检查将 C++ 应用程序移植到 Qt 6
  • 生命涌现的小龙虾技能之【Cat Face Recognition Skill | 猫脸识别技能】简介
  • 每个按键都能单独屏蔽!这款免费小工具,治好了我的误触强迫症
  • 客户拜访录制了需求沟通短视频,2026教你搞定短视频文字提取难题
  • 速卖通商品信息自动翻译实现方案
  • 基于YOLO与边缘计算的垃圾自动分类系统:从数据到部署全流程实践