Docs Menu
Docs Home
/ /

Almacene archivos grandes

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.

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:

  • chunks colección, que almacena los fragmentos de archivos binarios

  • files colección, que almacena los metadatos del archivo

El driver crea el bucket de GridFS, si no existe, cuando se guardan por primera vez datos en él. El bucket contiene las colecciones anteriores con el prefijo del nombre de bucket por defecto fs, a menos que especifiques un nombre diferente. Para asegurar la recuperación eficiente de los archivos y metadatos relacionados, el controlador crea un índice en cada colección. El driver asegura que estos índices existan antes de realizar operaciones de lectura y escritura en el bucket de GridFS.

Para obtener más información sobre los índices GridFS,consulte Índices GridFS en el manual del servidor MongoDB.

Cuando se utiliza GridFS para almacenar archivos, el driver 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 un ID de archivo, nombre de archivo y otros metadatos del archivo. Puedes cargar el archivo pasando un flujo al controlador de C++ para que lo procese o crear un nuevo flujo y escribir directamente en él.

El siguiente diagrama muestra cómo GridFS divide los archivos cuando se cargan en un depósito:

Un diagrama que muestra cómo GridFS sube un archivo a un bucket

Al recuperar archivos, GridFS 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.

Para empezar a almacenar o recuperar archivos de GridFS, llame al método gridfs_bucket() en su base de datos. Este método accede a un depósito existente o crea uno nuevo si no existe.

El siguiente ejemplo llama al método gridfs_bucket() en la base de datos db:

auto bucket = db.gridfs_bucket();

Puede personalizar la configuración del bucket de GridFS pasando una instancia de la clase mongocxx::options::gridfs::bucket como argumento opcional al método gridfs_bucket(). La siguiente tabla describe los campos que puede configurar en una instancia mongocxx::options::gridfs::bucket:

Campo
Descripción

bucket_name

Specifies the bucket name to use as a prefix for the files and chunks collections. The default value is "fs".
Type: std::string

chunk_size_bytes

Specifies the chunk size that GridFS splits files into. The default value is 261120.
Type: std::int32_t

read_concern

Specifies the read concern to use for bucket operations. The default value is the database's read concern.
Type: mongocxx::read_concern

read_preference

Specifies the read preference to use for bucket operations. The default value is the database's read preference.
Type: mongocxx::read_preference

write_concern

Specifies the write concern to use for bucket operations. The default value is the database's write concern.
Type: mongocxx::write_concern

El siguiente ejemplo crea un bucket llamado "myCustomBucket" configurando el campo bucket_name de una instancia mongocxx::options::gridfs::bucket:

mongocxx::options::gridfs::bucket opts;
opts.bucket_name("myCustomBucket");
auto bucket = db.gridfs_bucket(opts);

Puede cargar archivos a un depósito GridFS mediante los siguientes métodos:

Utilice el método open_upload_stream() para crear un flujo de carga para un nombre de archivo determinado. El método open_upload_stream() permite especificar información de configuración en una instancia options::gridfs::upload, que puede pasar como parámetro.

Este ejemplo utiliza un flujo de carga para realizar las siguientes acciones:

  • Establece el campo chunk_size_bytes de una instancia de opciones

  • Abre una secuencia grabable para un nuevo archivo GridFS llamado "my_file" y aplica la opción chunk_size_bytes

  • Llama al método write() para escribir datos en my_file, al que apunta la secuencia

  • Llama al método close() para cerrar la secuencia que apunta a my_file

mongocxx::options::gridfs::upload opts;
opts.chunk_size_bytes(1048576);
auto uploader = bucket.open_upload_stream("my_file", opts);
// ASCII for "HelloWorld"
std::uint8_t bytes[10] = {72, 101, 108, 108, 111, 87, 111, 114, 108, 100};
for (auto i = 0; i < 5; ++i) {
uploader.write(bytes, 10);
}
uploader.close();

Utilice el método upload_from_stream() para cargar el contenido de una secuencia a un nuevo archivo GridFS. El método upload_from_stream() permite especificar información de configuración en una instancia options::gridfs::upload, que puede pasar como parámetro.

Este ejemplo realiza las siguientes acciones:

  • Abre un archivo ubicado en /path/to/input_file como una secuencia en modo de lectura binaria

  • Llama al método upload_from_stream() para cargar el contenido de la transmisión a un archivo GridFS llamado "new_file"

std::ifstream file("/path/to/input_file", std::ios::binary);
bucket.upload_from_stream("new_file", &file);

En esta sección, puedes aprender a recuperar metadatos de archivos almacenados en la colección files del depósito de GridFS. Los metadatos contienen información sobre el archivo al que se refieren, incluyendo:

  • El _id del archivo

  • El nombre del archivo

  • La longitud/tamaño del archivo

  • La fecha y hora de carga

  • Un documento metadata en el que puedes almacenar otra información

Para recuperar archivos de un bucket de GridFS, llame al método mongocxx::gridfs::bucket::find() en su bucket. El método devuelve una instancia mongocxx::cursor desde la que puede acceder a los resultados. Para obtener más información sobre los cursores, consulte Guíade acceso a datos desde un cursor.

El siguiente ejemplo de código muestra cómo recuperar e imprimir metadatos de archivos en un bucket de GridFS. Utiliza un bucle for para iterar sobre el cursor devuelto y mostrar el contenido de los archivos cargados en los ejemplos de Cargar Archivos:

auto cursor = bucket.find({});
for (auto&& doc : cursor) {
std::cout << bsoncxx::to_json(doc) << std::endl;
}
{ "_id" : { "$oid" : "..." }, "length" : 13, "chunkSize" : 261120, "uploadDate" :
{ "$date" : ... }, "filename" : "new_file" }
{ "_id" : { "$oid" : "..." }, "length" : 50, "chunkSize" : 1048576, "uploadDate" :
{ "$date" : ... }, "filename" : "my_file" }

El find() método acepta varias especificaciones de consulta. Puede usar su mongocxx::options::find parámetro para especificar el orden de clasificación, el número máximo de documentos a devolver y el número de documentos que se omitirán antes de devolver. Para ver una lista de las opciones disponibles, consulte la documentación de la API.

Puede descargar archivos de un depósito GridFS mediante los siguientes métodos:

Puede descargar archivos de su base de datos MongoDB utilizando el método open_download_stream() para crear un flujo de descarga.

Este ejemplo utiliza un flujo de descarga para realizar las siguientes acciones:

  • Recupera el valor _id del archivo GridFS llamado "new_file"

  • Pasa el valor _id al método open_download_stream() para abrir el archivo como una secuencia legible

  • Crea un vector buffer para almacenar el contenido del archivo

  • Llama al método read() para leer el contenido del archivo desde el flujo downloader al vector

auto doc = db["fs.files"].find_one(make_document(kvp("filename", "new_file")));
auto id = doc->view()["_id"].get_value();
auto downloader = bucket.open_download_stream(id);
std::vector<uint8_t> buffer(downloader.file_length());
downloader.read(buffer.data(), buffer.size());

Puede descargar el contenido de un archivo GridFS a una transmisión existente llamando al método download_to_stream() en su bucket.

Este ejemplo realiza las siguientes acciones:

  • Abre un archivo ubicado en /path/to/output_file como una secuencia en modo de escritura binaria

  • Recupera el valor _id del archivo GridFS llamado "new_file"

  • Pasa el valor _id a download_to_stream() para descargar el archivo a la transmisión

std::ofstream output_file("/path/to/output_file", std::ios::binary);
auto doc = db["fs.files"].find_one(make_document(kvp("filename", "new_file")));
auto id = doc->view()["_id"].get_value();
bucket.download_to_stream(id, &output_file);

Utilice el método delete_file() para eliminar el documento de colección de un archivo y los fragmentos asociados de su bucket. Esto elimina el archivo. Debe especificar el archivo por su campo _id en lugar de por su nombre.

El siguiente ejemplo muestra cómo eliminar un archivo llamado "my_file" pasando su valor _id a delete_file():

auto doc = db["fs.files"].find_one(make_document(kvp("filename", "my_file")));
auto id = doc->view()["_id"].get_value();
bucket.delete_file(id);

Nota

Revisiones de archivos

El método delete_file() 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 al método delete_file().

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:

Volver

Guardado masivo

En esta página