Overview
En esta guía, aprenderá a almacenar y recuperar archivos grandes en MongoDB usando GridFS. GridFS es una especificación implementada por el controlador de C que describe cómo dividir archivos en fragmentos al almacenarlos y reensamblarlos al recuperarlos. La implementación de GridFS en el controlador es una abstracción que gestiona las operaciones y la organización del almacenamiento de archivos.
Utilice GridFS si el tamaño de sus archivos supera el límite de tamaño de documento BSON de 16MB. Para obtener información más detallada sobre si GridFS es adecuado para su caso de uso, consulte GridFS en el manual del servidor MongoDB.
Cómo funciona GridFS
GridFS organiza los archivos en un bucket, un grupo de colecciones de MongoDB que contiene los fragmentos de archivos y la información que los describe. El bucket contiene las siguientes colecciones, nombradas según la convención definida en la especificación de GridFS:
El
chunksLa colección almacena los fragmentos de archivos binarios.La colección
filesalmacena los metadatos del archivo.
El controlador crea el depósito GridFS, si no existe, al realizar la primera operación de escritura. El depósito contiene las colecciones anteriores con el prefijo fs, a menos que se especifique otro. Para garantizar una recuperación eficiente de los archivos y metadatos relacionados, el controlador también crea un índice para cada colección si no existen y cuando el depósito está vacío.
Para obtener más información sobre los índices GridFS,consulte Índices GridFS en el manual del servidor MongoDB.
Al usar GridFS para almacenar archivos, el controlador divide los archivos en fragmentos más pequeños, cada uno representado por un documento independiente en la colección chunks. También crea un documento en la colección files que contiene el ID, el nombre y otros metadatos del archivo. Puede cargar el archivo pasando una secuencia al controlador de C para que la consuma o creando una nueva secuencia y escribiendo en ella directamente.
El siguiente diagrama muestra cómo GridFS divide los archivos cuando se cargan en un depósito:

Al recuperar archivos de GridFS, este obtiene los metadatos de la colección files en el contenedor especificado y utiliza la información para reconstruir el archivo a partir de los documentos de la colección chunks. Puede leer el archivo escribiendo su contenido en una secuencia existente o creando una nueva que apunte al archivo.
Crear un bucket de GridFS
Para usar GridFS, primero llame a la función mongoc_gridfs_bucket_new(). Esta función crea una nueva estructura mongoc_gridfs_bucket_t o accede a una mongoc_gridfs_bucket_t existente y acepta los siguientes parámetros:
Base de datos: especifica la base de datos en la que se creará el depósito.
Documento de opciones: especifica opciones para personalizar el depósito o
NULLPreferencia de lectura: especifica la preferencia de lectura que se debe utilizar en las operaciones de lectura, o
NULLpara heredar la preferencia de lectura de la base de datosUbicación del error: especifica una ubicación para un valor de error o
NULL
El siguiente ejemplo llama a la función mongoc_gridfs_bucket_new() y pasa la base de datos db como parámetro:
mongoc_database_t *db = mongoc_client_get_database(client, "db"); bson_error_t error; mongoc_gridfs_bucket_t *bucket = mongoc_gridfs_bucket_new(db, NULL, NULL, &error); if (!bucket) { fprintf(stderr, "Failed to create bucket: %s\n", error.message); }
Personaliza el cubo
Puede personalizar la configuración del bucket de GridFS pasando un documento BSON que especifique valores de opción a la función mongoc_gridfs_bucket_new(). La siguiente tabla describe las opciones que puede configurar en el documento:
Opción | Descripción |
|---|---|
| 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 |
El siguiente ejemplo crea un depósito llamado "myCustomBucket" al pasar un documento de opciones a mongoc_gridfs_bucket_new() que establece la opción 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); }
Cargar archivos
Puede cargar archivos en un bucket GridFS utilizando las siguientes funciones:
mongoc_gridfs_bucket_open_upload_stream(): Abre un nuevo flujo de carga al que se pueden guardar los contenidos del archivomongoc_gridfs_bucket_upload_from_stream(): Carga el contenido de una transmisión existente a un archivo GridFS
Escribir en un flujo de carga
Utilice la función mongoc_gridfs_bucket_open_upload_stream() para crear un flujo de carga para un nombre de archivo determinado. La función mongoc_gridfs_bucket_open_upload_stream() permite especificar información de configuración en un documento de opciones, que puede pasar como parámetro.
Este ejemplo utiliza un flujo de carga para realizar las siguientes acciones:
Abre una secuencia escribible para un nuevo archivo GridFS llamado
"my_file"Llama a la función
mongoc_stream_write()para escribir datos en"my_file", al que apunta la secuenciaLlama a las funciones
mongoc_stream_close()ymongoc_stream_destroy()para cerrar y destruir la secuencia que apunta a"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);
Subir una transmisión existente
Utiliza la función mongoc_gridfs_bucket_upload_from_stream() para subir el contenido de un flujo a un nuevo archivo GridFS. La función mongoc_gridfs_bucket_upload_from_stream() te permite especificar la información de configuración en un documento de opciones, que puedes pasar como parámetro.
Este ejemplo realiza las siguientes acciones:
Llama a la función
mongoc_stream_file_new_for_path()para abrir un archivo ubicado en/path/to/input_filecomo una secuencia en modo de solo lectura (O_RDONLY)Llama a la función
mongoc_gridfs_bucket_upload_from_stream()para cargar el contenido de la transmisión a un archivo GridFS llamado"new_file"Llama a las funciones
mongoc_stream_close()ymongoc_stream_destroy()para cerrar y destruir la secuencia
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 información del archivo
En esta sección, aprenderá a recuperar los metadatos de archivos almacenados en la colección files del bucket GridFS. Los metadatos de un archivo contienen información sobre el archivo al que hace referencia, incluyendo:
El
_iddel archivoEl nombre del archivo
La longitud/tamaño del archivo
La fecha y hora de carga
Un documento
metadataen el que puedes almacenar cualquier otra información
Para recuperar archivos de un bucket de GridFS, llame a la función mongoc_gridfs_bucket_find() y pase su bucket como parámetro. La función devuelve un cursor desde el que puede acceder a los resultados.
Tip
Para obtener más información sobre los cursores en el controlador C, consulte Guíade acceso a datos desde un cursor.
Ejemplo
El siguiente ejemplo de código muestra cómo recuperar e imprimir metadatos de archivos en un bucket de GridFS. Utiliza un bucle while para iterar sobre el cursor devuelto y mostrar el contenido de los archivos cargados en los ejemplos de Cargar Archivos:
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_relaxed_extended_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" : { } }
La mongoc_gridfs_bucket_find() función acepta varias especificaciones de consulta. Puede usar su parámetro de opciones para especificar el orden de clasificación, el número máximo de documentos a devolver y el número de documentos a omitir antes de devolver. Para ver una lista de las opciones disponibles, consulte la documentación de la API mongoc_collection_find_with_opts().
Descarga de archivos
Puede descargar archivos de un depósito GridFS mediante las siguientes funciones:
mongoc_gridfs_bucket_open_download_stream():Abre un nuevo flujo de descarga desde el que puedes leer el contenido del archivomongoc_gridfs_bucket_download_to_stream(): Escribe el archivo completo en un flujo de descarga existente
Leer desde un flujo de descarga
Puede descargar archivos de su base de datos MongoDB utilizando la función mongoc_gridfs_bucket_open_download_stream() para crear un flujo de descarga.
Este ejemplo utiliza un flujo de descarga para realizar las siguientes acciones:
Llama a la función
mongoc_gridfs_bucket_open_download_stream()para seleccionar un archivo GridFS con el valor_idespecificado y lo abre como una secuencia legibleLlama a la función
mongoc_stream_read()para leer el contenido del archivoLlama a las funciones
mongoc_stream_close()ymongoc_stream_destroy()para cerrar y destruir el flujo de descarga que apunta al archivo
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);
Nota
Si hay varios documentos con el mismo nombre de archivo, GridFS transmitirá el archivo más reciente con el nombre dado (según lo determinado por el campo uploadDate).
Descargar a una transmisión existente
Puede descargar el contenido de un archivo GridFS a una transmisión existente llamando a la función mongoc_gridfs_bucket_download_to_stream().
Este ejemplo realiza las siguientes acciones:
Llama a la función
mongoc_stream_file_new_for_path()para abrir un archivo ubicado en/path/to/output_filecomo una secuencia en modo de lectura y escritura (O_RDWR)Descarga un archivo GridFS que tiene el valor
_idespecificado en la transmisiónLlama a las funciones
mongoc_stream_close()ymongoc_stream_destroy()para cerrar y destruir el flujo de archivos
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);
Eliminar archivos
Use la función mongoc_gridfs_bucket_delete_by_id() para eliminar el documento de colección de un archivo y los fragmentos asociados de su bucket. Esto elimina el archivo.
El siguiente ejemplo le muestra cómo eliminar un archivo haciendo referencia a su 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); }
Nota
Revisiones de archivos
La función mongoc_gridfs_bucket_delete_by_id() solo permite eliminar un archivo a la vez. Si desea eliminar cada revisión de archivo, o archivos con diferentes tiempos de carga que comparten el mismo nombre, recopile los valores _id de cada revisión. Luego, pase cada valor _id en llamadas separadas a la función mongoc_gridfs_bucket_delete_by_id().
Documentación de la API
Para obtener más información sobre el uso del controlador C para almacenar y recuperar archivos grandes, consulte la siguiente documentación de API: