迹忆客 专注技术分享

当前位置:主页 > 学无止境 > 数据库 > MongoDB >

在 PHP 中使用 MongoDB 作为文件存储

作者:迹忆客 最近更新:2023/04/20 浏览次数:

在为大文件创建可扩展存储方面,MongoDB 及其 GridFS(使用 MongoDB 查询语言 - MQL 编写)是市场上最好的文件存储解决方案之一。 在本教程中,您将学习如何在 PHP 中使用 MongoDB 作为文件存储。

它简化了查询文件集合的任何部分的过程,并通过将所需的数据加载到您的工作集中(工作集代表一组数据或加载的数据)来产生与任何其他查询相同的过程 给定时间)MongoDB 在给定时间范围内需要提高或保持最佳性能。 此外,它通过将其分页到 RAM 中来进行查询(存储、传输、数据/文件操作)。

它的读取性能各不相同,因为它对于直接从 RAM 中读取的小文件非常出色,另一方面,对于大文件可能更好。 预计大多数计算机不会有 600+ GB 的 RAM,并且可以轻松处理单个 mongod 实例上单个文件的 600+ GB 分区。

这里要考虑的一件重要事情是,块的默认或平均大小为 256KB,这使得 600GB 文件集合的文档量很大; 但是,您可以在大多数驱动程序中操作此设置。 与任何其他集合一样,GridFS 使用默认锁(数据库级别 2.2+ 或全局级别 pre-2.2)。

数据库级别 2.2+ 和全局级别 pre-2.2 确实相互干扰,并且通过深入理解,您可以确保对正在编写的文档的读取一致。

实现了驱动的服务器意味着它对GridFS一无所知,服务器端也没有对GridFS数据的特殊解析。 您将学习如何在您的 PHP 项目中使用 MongoDB 实现 GridFS,并且有可能根据您的具体场景、流量、并发写入/读取的数量以及许多其他因素发生争用,因此可能存在任何读取/锁定 在某些情况下写操作。


使用 MongoDB 的 GridFS 作为文件存储

文件大小增加(超过 BSON 文件的 16MB 默认限制)需要更强大的存储系统,而 GridFS 能够处理大文件,因为它将文件分成块以将每个块作为单独的文件/文档存储/处理 而不是将文件存储为单个文档。 它的默认块大小为 255KB,它将它们存储在一个集合中,将文件元数据存储在另一个集合中。

系统级文件系统无法处理大文件,将它们存储在 MongoDB 数据库中效率更高。 GridFS 是一个完美的解决方案,可以在不将整个文档加载到内存的情况下访问大文件的部分信息,并且它是增加目录中数据/存储限制的性能最佳解决方案。

此外,它有助于文档、文件和元数据同步,并在使用地理分布式副本集(数据分发到多个 mongod 实例)时,跨多个系统部署数据以高效自动地分发文件及其元数据。 GridFS 方便程序员以两种方式存储和分发数据,包括使用 MongoDB 驱动程序或 mongofiles 命令行工具。

GridFS 使用两种类型的集合,包括块和文件集合。 此外,它表示 fs.chunks 的块集合和 fs.files 的文件集合,用于名为 fs 的 buck。

/*
prerequisites

i) MongoDB 3.0 or higher
ii) PHP Driver

[Remember| install both on the same server]

This example will store a >1GB video on a MongoDB server.

the source code `mkdir src` must be stored in a directory so create one
to create a successful connection and understanding between your files and storage, create a settings file
your new directory will contain a `Settings.php` file with the following PHP contents:
*/

<?php
    # Remember| PHP 7.0 allows you to have one `define` using an array
    define("USERNAME_MONGODB", "[your_username]");
    define("PASSWORD_MONGODB", "[your_password]");
    define("DATABASE_MONGODB", "[your_databaseName]");
    define("SERVERIP_MONGODB", "[your_serverIP or your_hostname]");

    // the following script will enable file storage so you can store a file
    require_once(__DIR__ . '/Settings.php');

    if (!isset($argv[1]))
    {
        die("Please mention/pass the filepath to the file you want to store in MongoDB Server.");
    }

    $storage_filepath = $argv[1];

    if (!file_exists($storage_filepath) || is_dir($storage_filepath))
    {
        die("Invalid! Please, re-check your filepath.");
    }


    function mongo_Connect($your_username, $your_password, $your_database, $your_host_serverIP)
    {
        $con_MongoDB = new Mongo("mongodb://{$your_username}:{$your_password}@{$your_host_serverIP}"); // Connect to Mongo Server
        $con_database = $con_MongoDB -> selectDB($your_database); // Connect to Database
        return $con_database;
    }

    $con_database = mongo_Connect(
        USERNAME_MONGODB,
        PASSWORD_MONGODB,
        DATABASE_MONGODB,
        SERVERIP_MONGODB
    );

    $grid_FS = $con_database -> getGridFS();

    # you can stick any metadata here, e.g., upload the owner's ID, date of execution, etc.
    $add_metadata = array("date" => new MongoDate());
    $storage_filepath = $storage_filepath;
    $grid_FS -> storeFile($storage_filepath, array("metadata" => $add_metadata));

    // You can execute the script using the php `StoreFile.php` "filename.com.avi"
    // list files with the file size
    require_once(__DIR__ . '/Settings.php');

    function _mongoConnect($your_username, $your_password, $your_database, $your_host_serverIP)
    {
        $con_MongoDB = new Mongo("mongodb://{$your_username}:{$your_password}@{$your_host_serverIP}"); // Connect to Mongo Server
        $con_database = $con_MongoDB -> selectDB($your_database); // Connect to Database
        return $con_database;
    }

    $con_database = _mongoConnect(
        USERNAME_MONGODB,
        PASSWORD_MONGODB,
        DATABASE_MONGODB,
        SERVERIP_MONGODB
    );

    $grid_FS = $con_database -> getGridFS();

    # Loop over the files and output their names and file sizes
    $storage_files = $grid_FS -> find();

    while (($your_file = $storage_files -> getNext()) != null)
    {
        print $your_file -> getFilename() . "\t" . $your_file -> getSize() . PHP_EOL;
    }

    // retrieve files
    require_once(__DIR__ . '/Settings.php');

    if (!isset($argv[1]))
    {
        die("Please mention/pass the filepath to the file you want to store in MongoDB Server.");
    }

    $storage_filepath = $argv[1];

    if (!file_exists($storage_filepath) || is_dir($storage_filepath))
    {
        die("Invalid! Please, re-check your filepath.");
    }

    function mongoConnect($your_username, $your_password, $your_database, $your_host_serverIP)
    {
        $con_MongoDB = new Mongo("mongodb://{$your_username}:{$your_password}@{$your_host_serverIP}"); // Connect to Mongo Server
        $con_database = $con_MongoDB -> selectDB($your_database); // Connect to Database
        return $con_database;
    }

    $con_database = mongoConnect(
        USERNAME_MONGODB,
        PASSWORD_MONGODB,
        DATABASE_MONGODB,
        SERVERIP_MONGODB
    );

    $grid_FS = $con_database -> getGridFS();

    # in the following code, you can search for the filepath passed in as the first argument
    $search_fileParams = array("filename" => $storage_filepath);

    if (false)
    {
        # If you used absolute paths when storing files, then you could use the following to download a folder's contents.
        $folder = '/path/to/folder';

        # Refer to https://secure.php.net/manual/en/class.mongoregex.php
        $file_get_filename = new MongoRegex("/^$folder");

        $search_fileParams = array(
            'filename' => $file_get_filename
        );
    }

    # Alternatively, use findOne($search_fileParams) if you expect only one file with the provided name.
    $storage_files = $grid_FS -> find($search_fileParams);

    while (($your_file = $storage_files -> getNext()) != null)
    {
        # Use a random string in case there is a file with the same name in the current directory.
        $random_string = substr(str_shuffle(MD5(microtime())), 0, 10);
        $outputFile_path = __DIR__ . '/' . $random_string . "_" . basename($your_file -> getFilename());
        $your_file -> write($outputFile_path);
        print "Retrieved: " . $outputFile_path . PHP_EOL;
    }

    // use the script like
    // php RetrieveFiles.php "my_filename.mp4"
?>

输出:

Retrieved: my_filename.mp4

如果您正在开发 PHP 网站而不是 CLI 工具(而不是使用 StoreFile() 方法),请使用 StoreUpload() 方法。 使用相对路径或完整路径在系统中存储文件,MongoDB 中存储的文件名将是完整路径时传入的确切字符串,例如 /path/to/file.mp4,文件名将是 相同。

请记住,对同一个文件多次调用脚本不会失败; 但是,这样做会浪费宝贵的存储资源,多次存储同一个文件。 PHP 代码示例向您展示了如何使用 MongoDB 作为您的 PHP 网站或项目的默认存储。

Hadoop 及其 HDFS 是 MongoDB 的一个很好的替代品,但它非常复杂; 但是,与 MongoDB 相比,它支持 Map/Reduce 作业。 最重要的是,GridFS 是一流的选择,因为它的实现是驱动程序本身的客户端(无需特殊加载或理解文件的上下文)。

MongoDB 及其 GridFS 是驱动程序实现的,并且规范可能会有所不同,因为驱动程序将允许您从文件集合中查询文档集合,并使程序员能够稍后通过单个查询从块集合中提供文件本身。 它简化了将文件集合和后续块集合加载到您的工作集中的过程。

转载请发邮件至 1244347461@qq.com 进行申请,经作者同意之后,转载请以链接形式注明出处

本文地址:

相关文章

比较 MongoDB 中的字段

发布时间:2023/04/21 浏览次数:51 分类:MongoDB

在本文中,我们将了解如何比较 MongoDB 中的两个字段。 此外,我们将看到一个相关的示例和解释,以使主题更容易理解。

清除或删除 MongoDB 中的集合

发布时间:2023/04/21 浏览次数:147 分类:MongoDB

本篇文章将告诉大家如何删除 MongoDB 数据库中的集合以及删除 MongoDB 中的集合的不同方法。

MongoDB 截断集合

发布时间:2023/04/21 浏览次数:178 分类:MongoDB

可以根据需要选择两个选项之一来截断下面的集合。 在今天的文章中,我们将学习如何在 MongoDB 中截断集合。

删除 MongoDB 中的重复项

发布时间:2023/04/21 浏览次数:151 分类:MongoDB

在本文中,我们将了解如何删除 MongoDB 中的重复条目,并且我们还将看到一个带有适当解释的示例,以使主题更容易理解。

使用 NodeJS 检查 MongoDB 中是否存在集合

发布时间:2023/04/21 浏览次数:194 分类:MongoDB

在本文中,我们将检查 MongoDB 数据库中是否存在一个集合,并且我们还将查看与主题相关的示例,以使主题更容易理解。 为此,我们将使用 Node.js。

MongoDB 中的唯一索引

发布时间:2023/04/21 浏览次数:144 分类:MongoDB

在这篇教学文章中,您将了解唯一索引、它们是什么以及如何在 MongoDB 中使索引唯一。 此外,还简要详细地解释了使用户的电子邮件在 MongoDB 中唯一。

在 MongoDB 中创建索引

发布时间:2023/04/21 浏览次数:104 分类:MongoDB

索引有助于有效解决查询。 如果没有索引,MongoDB 必须遍历集合中的每个文档才能找到与查询匹配的文档。因此,在今天的文章中,我们将学习如何在 MongoDB 中创建索引。

MongoDB 中的稀疏索引

发布时间:2023/04/21 浏览次数:142 分类:MongoDB

在本文中,我们将讨论 MongoDB 中的稀疏索引。 此外,我们将提供一个相关示例并进行解释,以使该主题更容易理解。

扫一扫阅读全部技术教程

社交账号
  • https://www.github.com/onmpw
  • qq:1244347461

最新推荐

教程更新

热门标签

扫码一下
查看教程更方便