Armazenar arquivos grandes
Nesta página
- Visão geral
- Como funciona o GridFS
- Crie um intervalo GridFS
- Personalizar o bucket
- Fazer upload de arquivos
- Escrever em um fluxo de upload
- Carregar um stream existente
- Recuperar informações do arquivo
- Exemplo
- Baixar arquivos
- Ler de um fluxo de download
- Baixar uma revisão de arquivo
- Baixar em um stream existente
- Renomear arquivos
- Excluir arquivos
- Documentação da API
Visão geral
Neste guia, você pode aprender como armazenar e recuperar arquivos grandes no MongoDB usando GridFS. O GridFS é uma especificação implementada pela Biblioteca PHP do MongoDB que descreve como divisão os arquivos em blocos ao armazená-los e remontá-los ao recuperá-los. A implementação do GridFS da biblioteca é uma abstração que gerencia as operações e a organização do armazenamento de arquivos.
Use o GridFS se o tamanho dos seus arquivos exceder o limite de tamanho de documento BSON de 16MB. Para obter informações mais detalhadas sobre se o GridFS é adequado para seu caso de uso, consulte GridFS no manual do MongoDB Server .
Como funciona o GridFS
O GridFS organiza os arquivos em um bucket, um grupo de coleções do MongoDB que contém os blocos de arquivos e as informações que os descrevem. O bloco contém as seguintes coleções, nomeadas usando a convenção definida na especificação do GridFS:
A coleção
chunks
armazena os blocos de arquivo binário.A coleção
files
armazena os metadados do arquivo.
Quando você cria um novo bloco GridFS , a biblioteca cria as coleções anteriores, prefixadas com o nome de bloco padrão fs
, a menos que você especifique um nome diferente. A biblioteca também cria um índice em cada coleção para garantir a recuperação eficiente dos arquivos e metadados relacionados. A biblioteca cria o GridFS , se ele não existir, somente quando a primeira operação de gravação é executada. A biblioteca cria índices somente se eles não existirem e quando o bloco estiver vazio. Para obter mais informações sobre os índices do GridFS , consulte Índices do GridFS no manual do MongoDB Server .
Ao usar o GridFS para armazenar arquivos, a biblioteca divide os arquivos em partes menores, cada um representado por um documento separado na coleção chunks
. Ele também cria um documento na coleção files
que contém um ID de arquivo, nome de arquivo e outros metadados de arquivo. Você pode fazer upload do arquivo passando um stream para a Biblioteca PHP do MongoDB para consumir ou criar um novo stream e escrever diretamente nele. Para saber mais sobre fluxos,consulte Fluxos no manual do PHP.
Visualize o diagrama a seguir para ver como o GridFS divide os arquivos quando carregados em um bucket:
Ao recuperar arquivos, o GridFS obtém os metadados da coleção files
no bloco especificado e utiliza as informações para reconstruir o arquivo a partir de documentos na coleção chunks
. Você pode ler o arquivo gravando seu conteúdo em um fluxo existente ou criando um novo fluxo que aponte para o arquivo.
Crie um intervalo GridFS
Para armazenar ou recuperar arquivos do GridFS, chame o método MongoDB\Database::selectGridFSBucket()
no seu banco de dados de dados. Este método acessa um bucket existente ou cria um novo bucket se não existir.
O exemplo seguinte chama o método selectGridFSBucket()
no banco de dados de dados do db
:
$bucket = $client->db->selectGridFSBucket();
Personalizar o bucket
Você pode personalizar a configuração do bucket GridFS passando uma array que especifica valores de opção para o método selectGridFSBucket()
. A tabela a seguir descreve algumas opções que você pode definir na array:
Opção | Descrição |
---|---|
bucketName | Specifies the bucket name to use as a prefix for the files and chunks collections.
The default value is 'fs' .Type: string |
chunkSizeBytes | Specifies the chunk size that GridFS splits files into. The default value is 261120 .Type: integer |
readConcern | Specifies the read concern to use for bucket operations. The default value is the
database's read concern. Type: MongoDB\Driver\ReadConcern |
readPreference | Specifies the read preference to use for bucket operations. The default value is the
database's read preference. Type: MongoDB\Driver\ReadPreference |
writeConcern | Specifies the write concern to use for bucket operations. The default value is the
database's write concern. Type: MongoDB\Driver\WriteConcern |
O exemplo a seguir cria um bucket chamado 'myCustomBucket'
passando uma array para selectGridFSBucket()
que define a opção bucketName
:
$custom_bucket = $client->db->selectGridFSBucket( ['bucketName' => 'myCustomBucket'] );
Fazer upload de arquivos
Você pode fazer upload de arquivos para um bucket GridFS usando os seguintes métodos:
MongoDB\GridFS\Bucket::openUploadStream()
: abre um novo fluxo de upload para o qual você pode escrever conteúdo de arquivoMongoDB\GridFS\Bucket::uploadFromStream()
: carrega o conteúdo de um fluxo existente em um arquivo GridFS
Escrever em um fluxo de upload
Utilize o método openUploadStream()
para criar um fluxo de upload para um determinado nome de arquivo. O método openUploadStream()
permite a você especificar informações de configuração em uma array de opções, que você pode passar como um parâmetro.
Este exemplo usa um fluxo de upload para executar as seguintes ações:
Abre um fluxo gravável para um novo arquivo GridFS chamado
'my_file'
Define a opção
metadata
em um parâmetro de array para o métodoopenUploadStream()
Chama o método
fwrite()
para gravar dados em'my_file'
, para o qual o stream apontaChama o método
fclose()
para fechar o fluxo apontando para'my_file'
$stream = $bucket->openUploadStream('my_file', [ 'metadata' => ['contentType' => 'text/plain'] ]); fwrite($stream, 'Data to store'); fclose($stream);
Carregar um stream existente
Utilize o método uploadFromStream()
para carregar o conteúdo de um stream para um novo arquivo GridFS . O método uploadFromStream()
permite a você especificar informações de configuração em uma array de opções, que você pode passar como um parâmetro.
Este exemplo executa as seguintes ações:
Chama o método
fopen()
para abrir um arquivo localizado em/path/to/input_file
como um fluxo no modo de leitura binária (rb
)Chama o método
uploadFromStream()
para carregar o conteúdo do stream para um arquivo GridFS chamado'new_file'
$file = fopen('/path/to/input_file', 'rb'); $bucket->uploadFromStream('new_file', $file);
Recuperar informações do arquivo
Nesta seção, você pode aprender como recuperar metadados de arquivo armazenados na coleção files
do contêiner GridFS. Os metadados contêm informações sobre o arquivo a que se refere, incluindo:
O
_id
do arquivoO nome do arquivo
O tamanho/comprimento do arquivo
A data e a hora do carregamento
Um documento
metadata
no qual você pode armazenar qualquer outra informação
Para recuperar arquivos de um GridFS , chame o método MongoDB\GridFS\Bucket::find()
na instância do MongoDB\GridFS\Bucket
. O método retorna uma instância do MongoDB\Driver\Cursor
da qual você pode acessar os resultados. Para saber mais sobre Cursor
objetos na biblioteca MongoDB PHP, consulte o guia Acessar dados de um cursor .
Exemplo
O seguinte exemplo de código mostra como recuperar e imprimir metadados de arquivo de arquivos em um bucket GridFS . Ele usa um loop foreach
para iterar pelo cursor retornado e exibir o conteúdo dos arquivos carregados nos exemplos de Arquivos de upload :
$files = $bucket->find(); foreach ($files as $file_doc) { echo toJSON($file_doc), PHP_EOL; }
{ "_id" : { "$oid" : "..." }, "chunkSize" : 261120, "filename" : "my_file", "length" : 13, "uploadDate" : { ... }, "metadata" : { "contentType" : "text/plain" }, "md5" : "6b24249b03ea3dd176c5a04f037a658c" } { "_id" : { "$oid" : "..." }, "chunkSize" : 261120, "filename" : "new_file", "length" : 13, "uploadDate" : { ... }, "md5" : "6b24249b03ea3dd176c5a04f037a658c" }
O método find()
aceita várias especificações de query. Você pode usar seu parâmetro $options
para especificar a ordem de classificação, o número máximo de documentos a serem retornados e o número de documentos a serem ignorados antes de retornar. Para visualizar uma lista de opções disponíveis, consulte a documentação da API.
Observação
O exemplo anterior chama o método toJSON()
para imprimir metadados de arquivo como JSON estendido, definido no código a seguir:
function toJSON(object $document): string { return MongoDB\BSON\Document::fromPHP($document)->toRelaxedExtendedJSON(); }
Baixar arquivos
Você pode baixar arquivos de um bucket GridFS usando os seguintes métodos:
MongoDB\GridFS\Bucket::openDownloadStreamByName()
ouMongoDB\GridFS\Bucket::openDownloadStream()
: abre um novo fluxo de download do qual você pode ler o conteúdo do arquivoMongoDB\GridFS\Bucket::downloadToStream()
: grava o arquivo inteiro em um fluxo de download existente
Ler de um fluxo de download
Você pode baixar arquivos do seu banco de banco de dados MongoDB utilizando o método MongoDB\GridFS\Bucket::openDownloadStreamByName()
para criar um stream de download.
Este exemplo usa um fluxo de download para executar as seguintes ações:
Seleciona um arquivo GridFS chamado
'my_file'
, carregado no exemplo de Gravação em um Fluxo de Carregamento , e o abre como um fluxo legívelChama o método
stream_get_contents()
para ler o conteúdo de'my_file'
Imprime o conteúdo do arquivo
Chama o método
fclose()
para fechar o fluxo de download apontando para'my_file'
$stream = $bucket->openDownloadStreamByName('my_file'); $contents = stream_get_contents($stream); echo $contents, PHP_EOL; fclose($stream);
"Data to store"
Observação
Se houver vários documentos com o mesmo nome de arquivo, o GridFS transmitirá o arquivo mais recente com o nome fornecido (conforme determinado pelo campo uploadDate
).
Alternativamente, você pode utilizar o método MongoDB\GridFS\Bucket::openDownloadStream()
, que utiliza o campo _id
de um arquivo como um parâmetro:
$stream = $bucket->openDownloadStream(new ObjectId('66e0a5487c880f844c0a32b1')); $contents = stream_get_contents($stream); fclose($stream);
Observação
A API de streaming do GridFS não pode carregar blocos parciais. Quando um fluxo de download precisa extrair um bloco do MongoDB, ele puxa todo o bloco para a memória. O tamanho padrão do bloco de 255-kilobytes geralmente é suficiente, mas você pode reduzir o tamanho do bloco para reduzir a sobrecarga de memória ou aumentar o tamanho do bloco ao trabalhar com arquivos maiores. Para obter mais informações sobre como definir o tamanho do bloco, consulte a seção Personalizar o bloco desta página.
Baixar uma revisão de arquivo
Quando seu bucket contém vários arquivos com o mesmo nome de arquivo, o GridFS escolhe a versão carregada mais recentemente do arquivo por padrão. Para diferenciar os arquivos que têm o mesmo nome, o GridFS atribui a eles um número de revisão, ordenado por tempo de carregamento.
O número de revisão do arquivo original é 0
e o próximo número de revisão de arquivo mais recente é 1
. Você também pode especificar valores negativos que correspondem à recência da revisão. O valor de revisão -1
faz referência à revisão mais recente e -2
faz referência à próxima revisão mais recente.
Você pode instruir o GridFS a baixar uma revisão de arquivo específica passando uma array de opções para o método openDownloadStreamByName()
e especificando a opção revision
. O exemplo a seguir lê o conteúdo do arquivo original chamado 'my_file'
em vez da revisão mais recente:
$stream = $bucket->openDownloadStreamByName('my_file', ['revision' => 0]); $contents = stream_get_contents($stream); fclose($stream);
Baixar em um stream existente
Você pode baixar o conteúdo de um arquivo GridFS para um fluxo existente ligando para o método MongoDB\GridFS\Bucket::downloadToStream()
em seu bloco.
Este exemplo executa as seguintes ações:
Chama o método
fopen()
para abrir um arquivo localizado em/path/to/output_file
como um fluxo no modo de gravação binária (wb
)Baixa um arquivo GridFS que tem um valor
_id
deObjectId('66e0a5487c880f844c0a32b1')
para o fluxo
$file = fopen('/path/to/output_file', 'wb'); $bucket->downloadToStream( new ObjectId('66e0a5487c880f844c0a32b1'), $file, );
Renomear arquivos
Utilize o método MongoDB\GridFS\Bucket::rename()
para atualizar o nome de um arquivo GridFS em seu bucket. Você deve especificar o arquivo para renomear pelo campo _id
em vez do nome do arquivo.
O exemplo a seguir mostra como atualizar o filename
campo 'new_file_name'
para fazendo referência ao _id
campo de um documento:
$bucket->rename(new ObjectId('66e0a5487c880f844c0a32b1'), 'new_file_name');
Observação
Revisões de arquivos
O método rename()
aceita a atualização do nome de somente um arquivo por vez. Se você quiser renomear cada revisão de arquivo ou arquivos com tempos de carregamento diferentes que compartilham o mesmo nome de arquivo, colete os valores _id
de cada revisão. Em seguida, passe cada valor em chamadas separadas para o método rename()
.
Excluir arquivos
Use o método MongoDB\GridFS\Bucket::delete()
para remover o documento de collection de um arquivo e os chunks associados do seu bucket. Isso exclui efetivamente o arquivo. Você deve especificar o arquivo pelo campo _id
em vez do nome do arquivo.
O seguinte exemplo mostra como excluir um arquivo referenciando seu campo _id
:
$bucket->delete(new ObjectId('66e0a5487c880f844c0a32b1'));
Observação
Revisões de arquivos
O método delete()
suporta a exclusão de somente um arquivo de cada vez. Se você quiser excluir cada revisão de arquivo ou arquivos com tempos de carregamento diferentes que compartilham o mesmo nome de arquivo, colete os valores _id
de cada revisão. Em seguida, passe cada valor em chamadas separadas para o método delete()
.
Documentação da API
Para saber mais sobre como usar a biblioteca PHP do MongoDB para armazenar e recuperar arquivos grandes, consulte a seguinte documentação da API: