我错误地删除了上一个查询中的一些文档,有没有办法回滚我的上一个查询mongo集合。
这是我的最后一个查询:
db.datas.remove({ "name" : "some_x_name"})
是否有任何回滚/撤消选项?我可以取回我的数据吗?
没有回滚选项(在MongoDB上下文中为rollback has a different meaning),严格来说,没有返回这些文档的支持方法-注释中涵盖了您可以/应该采取的预防措施。如此说来,如果您正在运行副本集,甚至是单节点副本集,那么您都将拥有一个oplog
。用oplog
遮盖插入文档的时间,您也许可以将其恢复。
最简单的方法是举一个例子。我将使用一个简化的示例,其中仅包含100个需要还原的已删除文档。要超出此范围(大量文档,或者您可能只希望选择性地还原等),您可能想要更改代码以遍历游标,或者在MongoDB shell之外使用您选择的语言编写此代码。基本逻辑保持不变。
首先,让我们在数据库oplog
中创建示例集合foo
。我们将插入100个没有dropTest
字段的文档和100个具有相同name
字段的文档,以便以后可以将它们错误地删除:
name
现在,让我们模拟一下意外删除了100个use dropTest;
for(i=0; i < 100; i++){db.foo.insert({_id : i})};
for(i=100; i < 200; i++){db.foo.insert({_id : i, name : "some_x_name"})};
文档:
name
由于我们在副本集中运行,因此我们仍在> db.foo.remove({ "name" : "some_x_name"})
WriteResult({ "nRemoved" : 100 })
中记录了这些文档(正在插入),并且值得庆幸的是,这些插入还没有(还)落在oplog
的末尾([C0 ]是oplog
记住)。让我们看看是否可以找到它们:
oplog
该计数看起来正确,我们似乎仍在保存文件。从经验中我知道,我们在这里需要的capped collection条目的唯一部分是use local;
db.oplog.rs.find({op : "i", ns : "dropTest.foo", "o.name" : "some_x_name"}).count();
100
字段,所以让我们添加一个投影以仅返回该投影(为简洁起见,输出被删节,但您明白了):
oplog
要重新插入这些文档,我们可以将它们存储在一个数组中,然后遍历该数组并插入相关的片段。首先,让我们创建数组:
o
接下来,我们提醒自己,我们现在在集合中只有100个文档,然后遍历100个插入,最后重新验证计数:
db.oplog.rs.find({op : "i", ns : "dropTest.foo", "o.name" : "some_x_name"}, {"o" : 1});
{ "o" : { "_id" : 100, "name" : "some_x_name" } }
{ "o" : { "_id" : 101, "name" : "some_x_name" } }
{ "o" : { "_id" : 102, "name" : "some_x_name" } }
{ "o" : { "_id" : 103, "name" : "some_x_name" } }
{ "o" : { "_id" : 104, "name" : "some_x_name" } }
这里有警告,请注意:
var deletedDocs = db.oplog.rs.find({op : "i", ns : "dropTest.foo", "o.name" : "some_x_name"}, {"o" : 1}).toArray();
> deletedDocs.length
100
的格式被认为是内部的,可能随时更改(恕不另行通知,因此使用后果自负)>虽然我知道这有点古老,但我想分享我在这一领域研究过的东西,可能对遇到类似问题的其他人有用。