部分备份/恢复集合

Tho*_*aud 2 amazon-ec2 mongodb

我目前正在使用 AWS EC2 服务器,并且抓取了一些存储在 MongoDB 集合中的数据。这是我的数据库中唯一的集合。

现在我需要将此集合传输到我的本地计算机上进行处理。我的问题是远程计算机上的剩余磁盘空间不足以转储整个集合。空间可容纳约 60% 的藏品。我尝试使用db.copy()主机db.export()名直接在本地计算机上进行复制,但它不起作用,因为我不在本地网络上,而且即使使用 ssh 隧道,也存在一些身份验证问题。

我想做的是将我的大集合分成 2 个较小的集合并转储每个集合。是否可以?

谢谢你!

Bla*_*ven 6

您最好的选择是mongodump仅使用集合的一部分。这也是数据“批量迁移”的最佳选择,因此如果您可以更改主机之间的网络设置以允许这样做,那么有些使用部分可以适用于直接在主机之间工作。

如果您只需要使用mongodump集合的一部分,那么一般情况是应用该--query选项来选择您的输出。输出没有“限制”修饰符,因此您需要应用“范围查询”运算符,它们分别是$lte$gt

作为一个简单的示例集,请考虑以下数据:

{ "_id" : ObjectId("560e4a56a1a451fc8a37057f"), "list" : [ 1, 2, 3 ] }
{ "_id" : ObjectId("560e4a5ca1a451fc8a370580"), "list" : [ 1, 2 ] }
{ "_id" : ObjectId("560e4a62a1a451fc8a370581"), "list" : [ 1 ] }
{ "_id" : ObjectId("560e4a6ca1a451fc8a370582"), "list" : [ ] }
Run Code Online (Sandbox Code Playgroud)

因此,我们的想法是获取_id所需的“切点”处的值,并构造范围查询以仅选择这些范围内的文档。对于这个例子,我们将把输出分成两组。

因此,您想要的第一件事是_id第二个文档(成对)的,您可以通过在 mongo shell 中应用.skip()和来检索该文档:.limit()

db.sample.find().sort({ "_id": 1 }).skip(1).limit(1)
Run Code Online (Sandbox Code Playgroud)

这只是返回文档:

{ "_id" : ObjectId("560e4a5ca1a451fc8a370580"), "list" : [ 1, 2 ] }
Run Code Online (Sandbox Code Playgroud)

这是通过跳过n-1文档到您要在该批次中导出的数量,然后仅输出最后一个文档来完成的。

然后issedmongodump将包含范围选择器以$lte到达该点:

mongodump -d test -c sample \
--query '{ "_id": { "$lte": { "$oid": "560e4a5ca1a451fc8a370580" } } }' \
--out part1
Run Code Online (Sandbox Code Playgroud)

请注意$oid查询中的 。mongodump和工具mongoimport都使用MongoDB Extended JSON中描述的“严格”形式。shell 可用的帮助器构造函数并不是“严格的 JSON”,并且类似的工具(或带有选项的任何东西)只是使用 JSON 作为输入,因此此类数据以这种形式表示。ObjectId()mongodump--query

对于下一点,您希望获取n可以放入转储中的下一个文档。因此,您想通过跳过已输出的文档n加上下一个截止点的文档数量来查询下一个文档截止点n-1,或者基本上( 2 + 2 -1 ) = 3

db.sample.find().sort({ "_id": 1 }).skip(3).limit(1)
Run Code Online (Sandbox Code Playgroud)

$gt或者更好的是,应用您上次截止的范围:

db.sample.find({ "_id": { "$gt": ObjectId("560e4a5ca1a451fc8a370580") }}).skip(1).limit(1)
Run Code Online (Sandbox Code Playgroud)

无论哪种方式,您都会获得下一个截止文档:

{ "_id" : ObjectId("560e4a6ca1a451fc8a370582"), "list" : [ ] }
Run Code Online (Sandbox Code Playgroud)

然后对转储应用另一个范围查询,但这次同时使用$gt$lte运算符:

mongodump -d test -c sample \
--query '{ "_id": { 
    "$gt": { "$oid": "560e4a5ca1a451fc8a370580" },
    "$lte": { "$oid": "560e4a6ca1a451fc8a370582" } }}' \
--out part2
Run Code Online (Sandbox Code Playgroud)

与每个部分一样,您可以根据需要获取数据并将其移动到目标主机。请注意,在此形式中--out指定文件所在的目录

请注意,有些选项也可以在这里提供帮助,例如:

--host- (最好来自mongorestore)这可以让您在另一个系统上运行整个过程。例如,您可以在新的目标 MongoDB 实例中运行以下命令,将数据从源主机直接传输到mongorestore该系统上:

mongodump --host orighost -d test -c sample \
--query '{ "_id": { 
    "$gt": { "$oid": "560e4a5ca1a451fc8a370580" },
    "$lte": { "$oid": "560e4a6ca1a451fc8a370582" } }}' \
--out - \
| mongorestore -d newtest -c newsample --dir -
Run Code Online (Sandbox Code Playgroud)

注意-分别表示每个命令的标准输出/输入。

--gzip- 如果两台主机上都有 MongoDB 3.2,那么您还可以利用此选项来压缩/解压缩数据输出或流,如上面的管道中所示。与该管道选项相结合,它将是将数据迁移到新目标主机的最有效方法。

一般来说mongorestore,无论您如何应用它,数据都会愉快地重建集合,即使是部分集合。一般行为是标记为“仅插入”,因此不同的恢复将“添加”到集合中,但永远不会用相同的值“覆盖”_id数据。

仔细查看选项。特别是如果您的主机系统都位于 EC2 上,甚至都位于通用云资源内,那么您确实没有理由不能将输出从一个系统直接通过管道传输到另一个系统。所需要的只是在允许的主机之间进行一点防火墙配置。

但无论如何,如果您只想备份“部分”数据,那么这通常是执行此操作的方法。

当然,根据您自己的设置和身份验证需求,这两个命令可能需要除此处演示的其他选项。这里的选项只是“必需”选项,以便从“数据库”指定“集合”并使用“查询”进行过滤。