批量更新数据示例

最近更新时间:2024-10-15 19:27:51

我的收藏
本文基于如下图时间轴说明按 Key 闪回并进行数据更新的操作过程。


数据准备

1. 若原集合名为test,时间点 A,表里有三条数据,记录着三个人的分数(score),都是90分。

2. 时间点 C,对集合 test 中的三个人的分数(score)进行了更新,并增加了赵六的信息。


发现问题并发起按 Key 闪回

在时间点 D 发现,张三、李四和赵六的分数(score)存在问题,而王五的分数没有问题。为了解决这个问题,预将张三、李四和赵六的信息恢复到时间点 A和时间点 C 之间的时间点 B。于是使用张三、李四和赵六的_id字段,作为按 Key 闪回的筛选条件,使用按 Key 闪回功能将目标时间点数据进行回档。即在如下图的指定 Key 列表中选_id,在输入条件值的输入框中分行输入如下信息,发起按 Key 闪回任务。 ObjectId("652d2a6505726f70625ce5cf") ObjectId("652d2a6b05726f70625ce5d0") ObjectId("652d2beb05726f70625ce5d2")


更新数据步骤

等待按 Key 闪回任务执行完成,可按照如下步骤更新数据。

步骤1:确认闪回集合中的数据完整可用,以及是否有目标时间点缺失记录集合。

1. 执行 show collections 查看是否生成了闪回集合或缺失记录集合。如下图所示,test_bak1016151413 为闪回集合,test_bak_missing1016151413 为缺失记录集合。说明在目标回档时间点 B 时,存在指定 Key 的数据是还没有写入(即此时并没有赵六的数据),否则只会有闪回集合。

说明:
闪回集合名和缺失记录集合名中结尾的时间是操作时间,并非目标回档时间。
2. 利用按 Key 筛选的条件,分别计算 test 原集合、test_bak1016151413 闪回集合及其 test_bak_missing1016151413缺失集合的数据数目。
如下图所示,闪回集合里有2个,记录缺失集合里有1个,三条数据和原集合内的数据的_id字段都是一致的,加起来数目也符合预期。



步骤2:对比闪回集合中的数据和原集合中的数据,确认最终需要替换回原集合的id 及对应 Key 列表,同时将不需要的记录过滤掉。

查看闪回集合中的数据,确认是否符合按 Key 筛选条件,是否符合回到目标时间点 B 的数据要求,并选出要替换回原集合的数据的 id 及对应 Key列表。如下所示,闪回集合里的2条数据都符合时间点 B 的要求。


步骤3:根据选出的 Key 列表,匹配的文档,将文档按照 id 及对应的 Key通过 Upsert 方式写回原集合。

1. 使用 forEach 命令将闪回集合test_bak1016151413中 _id 对应文档更新到原集合test中。
db.test_bak1016151413.find({ _id: { $in: [ObjectId("652d2a6505726f70625ce5cf"), ObjectId("652d2a6b05726f70625ce5d0")] } }).forEach(function (doc) { db.test.updateOne({ _id: doc._id }, { $set: doc }, { upsert: true }); });
2. 查看原集合内数据符合预期。如下图所示,张三和李四的数据已更新回时间点 B 的状态,符合预期。


步骤4:如有缺失记录集合,按业务需求决定是否将原集合的对应记录删除。

若有缺失记录集合,说明目标时间点还没有该集合中的对应 id 的数据,根据情况考虑是否将原集合中对应 id 数据进行删除。如下图所示,赵六的数据在时间点B并不存在,这里如果判断需要清理该数据,则执行数据删除操作。

删除后,查看原集合内数据符合预期。