Visão geral
Neste guia, você pode aprender como armazenar e recuperar arquivos grandes no MongoDB usando GridFS. O GridFS é uma especificação implementada pelo driver C que descreve como divisão os arquivos em blocos ao armazená-los e remontá-los ao recuperá-los. A implementação do driver do GridFS é 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.
O driver cria o bucket GridFS , se ele não existir, quando você executa a primeira operação de gravação. O bucket contém as collections anteriores prefixadas com o nome de bucket padrão fs
, a menos que você especifique um nome diferente. Para garantir a recuperação eficiente dos arquivos e de seus respectivos metadados, o driver também cria um índice em cada collection, se não existirem, e quando o bucket 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, o driver 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 o driver C para consumir ou criar um novo stream e gravar diretamente nele.
O diagrama a seguir mostra como o GridFS divide os arquivos quando eles são carregados em um bucket:

Quando você recupera arquivos do GridFS, ele 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 usar o GridFS, primeiro chame a função mongoc_gridfs_bucket_new()
. Esta função cria uma nova estrutura mongoc_gridfs_bucket_t
ou acessa uma mongoc_gridfs_bucket_t
existente e aceita os seguintes parâmetros:
Banco de dados : especifica o banco de dados no qual criar o bucket
documento de opções : especifica opções para personalizar o bucket ou
NULL
Preferência de leitura: Especifica a preferência de leitura a ser usada para operações de leitura ou
NULL
para herdar a preferência de leitura do banco de dadosLocal do erro: especifica um local para um valor de erro ou
NULL
O exemplo seguinte chama a função mongoc_gridfs_bucket_new()
e passa o banco de dados do db
como um parâmetro:
mongoc_database_t *db = mongoc_client_get_database (client, "db"); bson_error_t error; if (!mongoc_gridfs_bucket_new (db, NULL, NULL, &error)) { fprintf (stderr, "Failed to create bucket: %s\n", error.message); }
Personalizar o bucket
Você pode personalizar a configuração do bucket GridFS passando um documento BSON que especifica valores de opção para a função mongoc_gridfs_bucket_new()
. A tabela a seguir descreve as opções que você pode definir no documento:
Opção | Descrição |
---|---|
| Specifies the bucket name to use as a prefix for the files and chunks collections.
The default value is "fs" .Type: string |
| Specifies the chunk size that GridFS splits files into. The default value is 255 kB. Type: int32 |
| Specifies the read concern to use for bucket operations. The default value is the
database's read concern. Type: mongoc_read_concern_t |
| Specifies the write concern to use for bucket operations. The default value is the
database's write concern. Type: mongoc_write_concern_t |
O exemplo a seguir cria um bucket chamado "myCustomBucket"
passando um documento de opções para mongoc_gridfs_bucket_new()
que define a opção bucketName
:
mongoc_database_t *db = mongoc_client_get_database (client, "db"); bson_t opts = BSON_INITIALIZER; BSON_APPEND_UTF8 (&opts, "bucketName", "myCustomBucket"); bson_error_t error; if (!mongoc_gridfs_bucket_new (db, &opts, NULL, &error)) { fprintf (stderr, "Failed to create bucket: %s\n", error.message); }
Fazer upload de arquivos
Você pode fazer upload de arquivos para um bucket GridFS usando as seguintes funções:
mongoc_gridfs_bucket_open_upload_stream()
: abre um novo fluxo de upload para o qual você pode escrever conteúdo de arquivomongoc_gridfs_bucket_upload_from_stream()
: carrega o conteúdo de um fluxo existente em um arquivo GridFS
Escrever em um fluxo de upload
Use a função mongoc_gridfs_bucket_open_upload_stream()
para criar um fluxo de upload para um determinado nome de arquivo. A função mongoc_gridfs_bucket_open_upload_stream()
permite especificar informações de configuração em um documento 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"
Chama a função
mongoc_stream_write()
para gravar dados em"my_file"
, para o qual o fluxo apontaChama as funções
mongoc_stream_close()
emongoc_stream_destroy()
para fechar e destruir o stream que aponta para"my_file"
bson_error_t error; mongoc_stream_t *upload_stream = mongoc_gridfs_bucket_open_upload_stream (bucket, "my_file", NULL, NULL, &error); if (upload_stream == NULL) { fprintf (stderr, "Failed to create upload stream: %s\n", error.message); } else { const char *data = "Data to store"; mongoc_stream_write (upload_stream, data, strlen(data), -1); } mongoc_stream_close (upload_stream); mongoc_stream_destroy (upload_stream);
Carregar um stream existente
Utilize a função mongoc_gridfs_bucket_upload_from_stream()
para carregar o conteúdo de um stream para um novo arquivo GridFS . A função mongoc_gridfs_bucket_upload_from_stream()
permite especificar informações de configuração em um documento de opções, que você pode passar como um parâmetro.
Este exemplo executa as seguintes ações:
Chama a função
mongoc_stream_file_new_for_path()
para abrir um arquivo localizado em/path/to/input_file
como um fluxo no modo somente leitura (O_RDONLY
)Chama a função
mongoc_gridfs_bucket_upload_from_stream()
para carregar o conteúdo do stream para um arquivo GridFS chamado"new_file"
Chama as funções
mongoc_stream_close()
emongoc_stream_destroy()
para fechar e destruir o stream
mongoc_stream_t *file_stream = mongoc_stream_file_new_for_path ("/path/to/input_file", O_RDONLY, 0); bson_error_t error; if (!mongoc_gridfs_bucket_upload_from_stream (bucket, "new_file", file_stream, NULL, NULL, &error)) { fprintf (stderr, "Failed to upload file: %s\n", error.message); } mongoc_stream_close (file_stream); mongoc_stream_destroy (file_stream);
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 de um arquivo 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 contêiner GridFS , chame a função mongoc_gridfs_bucket_find()
e passe seu contêiner como um parâmetro. A função retorna um cursor do qual você pode acessar os resultados.
Dica
Para saber mais sobre cursores no driver C, 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 while
para iterar pelo cursor retornado e exibir o conteúdo dos arquivos carregados nos exemplos de Arquivos de upload :
mongoc_cursor_t *cursor = mongoc_gridfs_bucket_find(bucket, bson_new(), NULL); const bson_t *file_doc; while (mongoc_cursor_next(cursor, &file_doc)) { char *json = bson_as_json(file_doc, NULL); printf("%s\n", json); bson_free(json); } mongoc_cursor_destroy (cursor);
{ "_id" : { "$oid" : "..." }, "length" : 13, "chunkSize" : 261120, "uploadDate" : { "$date" : ... }, "filename" : "my_file", "metadata" : { } } { "_id" : { "$oid" : "..." }, "length" : 13, "chunkSize" : 261120, "uploadDate" : { "$date" : ... }, "filename" : "new_file", "metadata" : { } }
The mongoc_gridfs_bucket_find()
function accepts various query specifications. You can use its options parameter to specify the sort order, maximum number of documents to return, and the number of documents to skip before returning. To view a list of available options, see the mongoc_collection_find_with_opts() API documentation.
Baixar arquivos
Você pode baixar arquivos de um bucket GridFS usando as seguintes funções:
mongoc_gridfs_bucket_open_download_stream()
: abre um novo fluxo de download do qual você pode ler o conteúdo do arquivomongoc_gridfs_bucket_download_to_stream()
: grava o arquivo inteiro em um fluxo de download existente
Ler de um fluxo de download
Você pode baixar arquivos do seu banco de dados MongoDB utilizando a função mongoc_gridfs_bucket_open_download_stream()
para criar um stream de download.
Este exemplo usa um fluxo de download para executar as seguintes ações:
Chama a função
mongoc_gridfs_bucket_open_download_stream()
para selecionar um arquivo GridFS com o valor_id
especificado e o abre como um fluxo legívelChama a função
mongoc_stream_read()
para ler o conteúdo do arquivoChama as funções
mongoc_stream_close()
emongoc_stream_destroy()
para fechar e destruir o fluxo de download que aponta para o arquivo
char buf[512]; bson_value_t file_id; file_id.value_type = BSON_TYPE_OID; bson_oid_init_from_string (&file_id.value.v_oid, "66fb1b8ea0f84a74ee099e71"); bson_error_t error; mongoc_stream_t *download_stream = mongoc_gridfs_bucket_open_download_stream (bucket, &file_id, &error); if (!download_stream) { fprintf (stderr, "Failed to create download stream: %s\n", error.message); } mongoc_stream_read (download_stream, buf, 1, 1, 0); mongoc_stream_close (download_stream); mongoc_stream_destroy (download_stream);
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
).
Baixar em um stream existente
Você pode baixar o conteúdo de um arquivo GridFS para um fluxo existente ligando para a função mongoc_gridfs_bucket_download_to_stream()
.
Este exemplo executa as seguintes ações:
Chama a função
mongoc_stream_file_new_for_path()
para abrir um arquivo localizado em/path/to/output_file
como um fluxo no modo leitura e escrita (O_RDWR
)Baixa um arquivo GridFS que tem o valor de
_id
especificado para o fluxoChama as funções
mongoc_stream_close()
emongoc_stream_destroy()
para fechar e destruir o fluxo de arquivos
mongoc_stream_t *file_stream = mongoc_stream_file_new_for_path ("/path/to/output_file", O_RDWR, 0); bson_error_t error; if (!file_stream) { fprintf (stderr, "Error opening file stream: %s\n", error.message); } bson_value_t file_id; file_id.value_type = BSON_TYPE_OID; bson_oid_init_from_string (&file_id.value.v_oid, "66fb1b8ea0f84a74ee099e71"); if (!mongoc_gridfs_bucket_download_to_stream (bucket, &file_id, file_stream, &error)) { fprintf (stderr, "Failed to download file: %s\n", error.message); } mongoc_stream_close (file_stream); mongoc_stream_destroy (file_stream);
Excluir arquivos
Use a função mongoc_gridfs_bucket_delete_by_id()
para remover o documento de collection de um arquivo e os chunks associados do seu bucket. Isso exclui efetivamente o arquivo.
O seguinte exemplo mostra como excluir um arquivo referenciando seu campo _id
:
bson_error_t error; bson_oid_t oid; bson_oid_init_from_string (&oid, "66fb1b365fd1cc348b031b01"); if (!mongoc_gridfs_bucket_delete_by_id (bucket, &oid, &error)) { fprintf (stderr, "Failed to delete file: %s\n", error.message); }
Observação
Revisões de arquivos
A função mongoc_gridfs_bucket_delete_by_id()
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 _id
em chamadas separadas para a função mongoc_gridfs_bucket_delete_by_id()
.
Documentação da API
Para saber mais sobre como usar o driver C para armazenar e recuperar arquivos grandes, consulte a seguinte documentação da API: