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 em um stream existente
- 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 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 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 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 |
---|---|
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 255 kB. Type: int32 |
readConcern | Specifies the read concern to use for bucket operations. The default value is the
database's read concern. Type: mongoc_read_concern_t |
writeConcern | 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 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 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" : { } }
A mongoc_gridfs_bucket_find()
função aceita várias especificações de query. Você pode usar seu parâmetro de opções 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 mongoc_collection_find_with_opts().
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 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: