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.
Utiliza GridFS si el tamaño de los archivos supera el límite del tamaño del documento BSON de 16MB. Para obtener información más detallada sobre si GridFS es adecuado para tu caso de uso, consulta GridFS en el manual del MongoDB Server.
Cómo funciona GridFS
GridFS organiza los archivos en un bucket, un grupo de colecciones de MongoDB que contienen los fragmentos de archivos e información que los describe. El bucket contiene las siguientes colecciones, nombradas según la convención definida en la especificación GridFS:
La
chunksla colección almacena los fragmentos de archivos binarios.La colección
filesalmacena los metadatos del archivo.
El driver crea el bucket de GridFS, si no existe, cuando ejecutas la primera operación de guardar. El bucket contiene las colecciones anteriores con el prefijo del nombre de bucket por defecto fs, a menos que indiques un nombre diferente. Para asegurar la recuperación eficiente de los archivos y metadatos relacionados, el driver también crea un índice en cada colección si no existen y cuando el bucket está vacío.
Para obtener más información sobre los índices de GridFS, consulta Índices de 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 bucket.

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 llama a la función mongoc_gridfs_bucket_new(). Esta función crea una nueva estructura mongoc_gridfs_bucket_t o accede a una existente mongoc_gridfs_bucket_t y acepta los siguientes parámetros:
Base de datos: Especifica la base de datos en la que se va a crear el bucket
Documento de opciones: especifica las opciones para personalizar el bucket, 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
Puedes personalizar la configuración del bucket GridFS pasando un documento BSON que especifique los valores de opción a la función mongoc_gridfs_bucket_new(). La siguiente tabla describe las opciones que puedes 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 contenedor llamado "myCustomBucket", pasando 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
Guardar 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 se puede pasar como parámetro.
Este ejemplo utiliza una transmisión de carga para realizar las siguientes acciones:
Abre un flujo escribible para un nuevo archivo GridFS llamado
"my_file"Llama a la función
mongoc_stream_write()para escribir datos en"my_file", a la que apunta el flujoLlama a las funciones
mongoc_stream_close()ymongoc_stream_destroy()para cerrar y destruir el flujo 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 un flujo 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 un stream en modo solo lectura (O_RDONLY)Llama a la función
mongoc_gridfs_bucket_upload_from_stream()para cargar el contenido del flujo a un archivo GridFS denominado"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 de archivos
En esta sección, puedes aprender cómo recuperar los metadatos de archivos almacenados en la colección files del bucket de GridFS. Los metadatos de un archivo contienen información sobre el archivo al que se refieren, 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 GridFS, llama a la función mongoc_gridfs_bucket_find() y pasa tu bucket como parámetro. La función devuelve un cursor desde el cual puedes acceder a los resultados.
Tip
Para aprender más sobre los cursores en el controlador de C, consulta el 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 función mongoc_gridfs_bucket_find() acepta varias especificaciones de query. Puedes 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 devolverlos. Para ver una lista de opciones disponibles, consulte la documentación de la API mongoc_collection_find_with_opts().
Descargar archivos
Puedes descargar archivos de un bucket de GridFS utilizando 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(): Guardar el archivo completo en un flujo de descarga existente
Leer desde un flujo de descarga
Puedes descargar archivos de tu 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 un flujo 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 en una transmisión existente
Puedes descargar el contenido de un archivo GridFS a un flujo 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 un flujo en modo de lectura y escritura (O_RDWR)Descarga un archivo GridFS que tiene el valor especificado
_idal flujoLlama 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);
Borrar archivos
Utiliza la función mongoc_gridfs_bucket_delete_by_id() para remover el documento de colección de un archivo y los fragmentos asociados de tu bucket. Esto borra efectivamente el archivo.
El siguiente ejemplo le muestra cómo borrar 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: