从MongoDB中提取文件



Office文档(Word、Excel、PDF)在过去10年里一直被上传到一个网站。该网站没有下载所有文件的方法,每次只能下载一个单独的文件。这需要几天才能完成,所以我联系了网站,要求他们提供所有的文件。他们提供了一个Mongo数据库转储,其中包括几个JSON和BSON文件,他们说这是他们提供文件的唯一方法。

我想从BSON文件中提取原始办公文档到我的Windows计算机中,如果可能的话,保留文件夹结构和元数据(文件创建时等)。

我在Windows 10电脑上安装了一个本地版本的Mongo,并导入了JSON和BSON文件。使用MongoDB Compass,我可以看到这些文件已被导入为集合,其中包括2.73GB的fs.chunks.bson文件,我假设该文件包含办公文档。我已经谷歌下一步应该是什么,但我不确定如何进行。如有任何帮助,不胜感激。

您需要做的是将转储恢复到数据库中,这可以使用mongorestore命令完成,一些GUI界面(如robo3T)也可以提供这样做的方法。请确保您的mongo版本与网站的mongo版本相同,否则您将面临数据损坏的风险,这将是一个痛苦的处理。

现在让我们来谈谈Mongo的文件系统GridFS,它有两个集合:fs.files集合包含文件元数据,而fs.chunks包含实际的文件数据。理论上,每个文件都有多个块,这种存储方法的目的是使流数据更有效。

要实际从GridFS读取文件,您必须首先从fs.files集合中获取每个文件文档,然后从fs.chunks集合中为每个文件获取匹配的块。一旦你获取了所有的块,你就可以"创建"了。你的文件,做任何你想做的事。

下面是需要做的sudo示例:

files = db.fs.files.find({});
... for each file ....
chunks = db.fs.chunks.find( { files_id: file._id } ).sort( { n: 1 } )
data = chuncks[0].data + .... + chunks[n].data;
...
do whatever you want with the data. remember to check the file type from the file metadata, different types will require different actions.

我必须做一些类似的事情。

首先,我恢复了文件和块BSON备份到我的MongoDB。

mongorestore -d db_name -c fs.chunks chunks.bson
mongorestore -d db_name -c fs.files files.bson

(注意需要将db_name替换为数据库名称)

这已经足够GridFS运行了。

接下来,我编写了一个脚本来从数据库中提取文件。我使用PHP来做到这一点,因为它已经设置在我工作的地方。请注意,我必须安装MongoDB驱动程序和库(使用composer)。如果你是在Windows上,很容易安装驱动器,你只需要从这里下载dll并将其放在php/ext文件夹中。然后在php.ini中添加以下内容:

extension=mongodb

下面是一个脚本的简单版本,将转储所有文件,它可以很容易地扩展到自定义文件夹,防止重叠的名称等。

include('vendor/autoload.php');
$client = new MongoDBClient("mongodb://localhost:27017");
$bucket = $client->local->selectGridFSBucket();
$files = $bucket->find();
foreach($files as $file){
$fileId = $file['_id'];
$filename = explode('.',$file['filename']);
$ext = $filename[1];
$filename = $filename[0];
$output = fopen('files/'.$filename.".".$ext, 'wb');
$bucket->downloadToStream($fileId, $output);
}

最新更新