Join us at MongoDB.local London on 7 May to unlock new possibilities for your data. Use WEB50 to save 50%.
Register now >
Docs Menu
Docs Home
/ /

GridFS

En esta guía, puedes aprender cómo almacenar y recuperar archivos grandes en MongoDB utilizando GridFS. GridFS es una especificación que describe cómo dividir archivos en fragmentos durante el almacenamiento y volver a ensamblarlos durante la recuperación. La implementación del driver Rust de GridFS gestiona las operaciones y la organización del almacenamiento de archivos.

Utiliza GridFS si el tamaño de tu archivo excede el límite del tamaño del documento BSON de 16 MB. GridFS también te ayuda a acceder a archivos sin cargar el archivo completo en memoria. Para obtener información más detallada sobre si GridFS es adecuado para tu caso de uso, consulta la PáginaGridFS en el manual del servidor.

Para obtener más información sobre GridFS, navegue a las siguientes secciones de esta guía:

GridFS organiza los archivos en un bucket, que es un grupo de colecciones de MongoDB que contiene fragmentos de archivos e información descriptiva. Los cubos contienen las siguientes colecciones, nombradas de acuerdo con la convención definida en la especificación de GridFS:

  • chunksque almacena los fragmentos del archivo binario

  • files, que almacena los metadatos del archivo

Cuando crea un nuevo depósito GridFS, el controlador Rust realiza las siguientes acciones:

  • Crea las colecciones chunks y files, con el prefijo del nombre del bucket por defecto fs, a menos que especifique un nombre diferente

  • Crea un índice en cada colección para garantizar la recuperación eficiente de archivos y metadatos relacionados

Puedes crear una referencia a un bucket GridFS siguiendo los pasos de la sección Referenciar un bucket GridFS de esta página. Sin embargo, el driver no crea un nuevo bucket GridFS y sus índices hasta que se realiza la primera operación de escritura. Para obtener más información sobre los índices de GridFS, consulta la página Índices de GridFS en el manual del servidor.

Al almacenar un archivo en un bucket de GridFS, el controlador de Rust crea los siguientes documentos:

  • Un documento en la colección files que almacena un ID de archivo único, un nombre de archivo y otros metadatos de archivo

  • Uno o más documentos en la colección chunks que almacenan el contenido del archivo, que el driver divide en partes más pequeñas

El siguiente diagrama describe cómo GridFS divide los archivos al cargarlos a un bucket:

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 bucket especificado y usa la información para reconstruir el archivo a partir de documentos en la colección chunks. Puede leer el archivo en la memoria o enviarlo a una secuencia.

Antes de almacenar archivos en un bucket GridFS, cree una referencia o obtenga una referencia a un bucket existente.

El siguiente ejemplo llama al método gridfs_bucket() en una instancia de base de datos, que crea una referencia a un bucket GridFS nuevo o existente:

let bucket = my_db.gridfs_bucket(None);

Puede especificar un nombre de depósito personalizado configurando el campo bucket_name de la estructura GridFsBucketOptions.

Nota

Creando instancias de estructuras

El controlador de Rust implementa el patrón de diseño Builder para la creación de algunos tipos de struct, incluido GridFsBucketOptions. Puedes usar el método builder() para construir una instancia de cada tipo encadenando métodos de opción builder.

La siguiente tabla describe los métodos que puede utilizar para configurar los campos GridFsBucketOptions:

Método
Possible Values
Descripción
bucket_name()
Any String value
Specifies a bucket name, which is set to fs by default

chunk_size_bytes()

Cualquier valor u32

Especifica el tamaño de fragmento utilizado para dividir el archivo, que por defecto es de 255 KB

write_concern()
WriteConcern::w(),
WriteConcern::w_timeout(),
WriteConcern::journal(),
WriteConcern::majority()
Specifies the bucket's write concern, which is set to the database's write concern by default

read_concern()

ReadConcern::local(), ReadConcern::majority(), ReadConcern::linearizable(), ReadConcern::available(), ReadConcern::snapshot()

Especifica la preocupación de lectura del depósito, que se establece en la preocupación de lectura de la base de datos de manera predeterminada

selection_criteria()
SelectionCriteria::ReadPreference,
SelectionCriteria::Predicate
Specifies which servers are suitable for a bucket operation, which is set to the database's selection
criteria by default

El siguiente ejemplo especifica opciones en una instancia GridFsBucketOptions para configurar un nombre de depósito personalizado y un límite de tiempo de cinco segundos para las operaciones de escritura:

let wc = WriteConcern::builder().w_timeout(Duration::new(5, 0)).build();
let opts = GridFsBucketOptions::builder()
.bucket_name("my_bucket".to_string())
.write_concern(wc)
.build();
let bucket_with_opts = my_db.gridfs_bucket(opts);

Puedes cargar un archivo en un bucket GridFS abriendo un flujo de carga y escribiendo tu archivo en el flujo. Llame el método open_upload_stream() en su instancia de bucket para abrir el flujo. Este método devuelve una instancia de GridFsUploadStream en la que puedes guardar el contenido del archivo. Para cargar el contenido del archivo en GridFsUploadStream, llama al método write_all() y pasa los bytes del archivo como parámetro.

Tip

Importar el módulo requerido

La estructura GridFsUploadStream implementa el atributo futures_io::AsyncWrite. Para usar los métodos de escritura AsyncWrite, como write_all(), importe el módulo AsyncWriteExt al archivo de su aplicación con la siguiente declaración de uso:

use futures_util::io::AsyncWriteExt;

El siguiente ejemplo utiliza un flujo de carga para cargar un archivo llamado "example.txt" a una cubeta de GridFS:

let bucket = my_db.gridfs_bucket(None);
let file_bytes = fs::read("example.txt").await?;
let mut upload_stream = bucket.open_upload_stream("example").await?;
upload_stream.write_all(&file_bytes[..]).await?;
println!("Document uploaded with ID: {}", upload_stream.id());
upload_stream.close().await?;

Puede descargar un archivo de un bucket de GridFS abriendo un flujo de descarga y leyendo desde él. Invoque el método open_download_stream() en la instancia del bucket, especificando el valor _id del archivo deseado como parámetro. Este método devuelve una instancia GridFsDownloadStream desde la que puede acceder al archivo. Para leer el archivo desde GridFsDownloadStream, invoque el método read_to_end() y pase un vector como parámetro.

Tip

Importar el módulo requerido

La estructura GridFsDownloadStream implementa la característica futures_io::AsyncRead. Para utilizar los métodos de lectura AsyncRead, como read_to_end(), importe el módulo AsyncReadExt a su archivo de aplicación con la siguiente declaración de uso:

use futures_util::io::AsyncReadExt;

El siguiente ejemplo utiliza un flujo de descarga para descargar un archivo con un valor _id de 3289 desde un depósito GridFS:

let bucket = my_db.gridfs_bucket(None);
let id = ObjectId::from_str("3289").expect("Could not convert to ObjectId");
let mut buf = Vec::new();
let mut download_stream = bucket.open_download_stream(Bson::ObjectId(id)).await?;
let result = download_stream.read_to_end(&mut buf).await?;
println!("{:?}", result);

Nota

La API de streaming de GridFS no puede cargar fragmentos parciales. Cuando un flujo de descarga necesita extraer un fragmento de MongoDB, lo extrae completo a memoria. El tamaño predeterminado de fragmento de 255 KB suele ser suficiente, pero se puede reducir para reducir la sobrecarga de memoria.

Puede recuperar información sobre los archivos almacenados en la colección files del bucket GridFS. Cada archivo se almacena como una instancia del tipo FilesCollectionDocument, que incluye los siguientes campos que representan información del archivo:

  • _id: el ID del archivo

  • length: el tamaño del archivo

  • chunk_size_bytes: el tamaño de los fragmentos del archivo

  • upload_date: la fecha y hora de carga del archivo

  • filename: el nombre del archivo

  • metadata: un documento que almacena metadatos especificados por el usuario

Llama al método find() en una instancia de un bucket de GridFS para recuperar archivos del bucket. El método devuelve una instancia de cursor desde la cual puedes acceder a los resultados.

El siguiente ejemplo recupera e imprime la longitud de cada archivo en un depósito GridFS:

let bucket = my_db.gridfs_bucket(None);
let filter = doc! {};
let mut cursor = bucket.find(filter).await?;
while let Some(result) = cursor.try_next().await? {
println!("File length: {}\n", result.length);
};

Tip

Para obtener más información sobre el método find(), consulte la Guía para recuperar datos. Para obtener más información sobre cómo recuperar datos desde un cursor, consulta la guía Acceso a datos usando un cursor.

Puedes actualizar el nombre de un archivo GridFS en tu bucket llamando al método rename() en una instancia del bucket. Transfiera el valor de _id del archivo de destino y el nuevo nombre del archivo como parámetros al método rename().

Nota

El método rename() solo permite actualizar el nombre de un archivo a la vez. Para renombrar varios archivos, recupere del depósito una lista de archivos que coincidan con el nombre, extraiga el campo _id de los archivos que desea renombrar y pase cada valor en llamadas separadas al método rename().

El siguiente ejemplo actualiza el campo filename del archivo que contiene un valor _id de 3289 a "new_file_name":

let bucket = my_db.gridfs_bucket(None);
let id = ObjectId::from_str("3289").expect("Could not convert to ObjectId");
let new_name = "new_file_name";
bucket.rename(Bson::ObjectId(id), new_name).await?;

Puedes usar el método delete() para remover un archivo de tu bucket. Para remover un archivo, llama a delete() en tu instancia de bucket y pasa el valor del _id del archivo como parámetro.

Nota

El método delete() solo permite eliminar un archivo a la vez. Para eliminar varios, recupere los archivos del depósito, extraiga el campo _id de los archivos que desea eliminar y pase cada valor _id en llamadas separadas al método delete().

El siguiente ejemplo elimina el archivo en el que el valor del campo _id es 3289:

let bucket = my_db.gridfs_bucket(None);
let id = ObjectId::from_str("3289").expect("Could not convert to ObjectId");
bucket.delete(Bson::ObjectId(id)).await?;

Puedes usar el método drop() para eliminar un bucket, lo que elimina las colecciones files y chunks. Para eliminar el bucket, llama a drop() en la instancia del bucket.

El siguiente ejemplo elimina un bucket de GridFS:

let bucket = my_db.gridfs_bucket(None);
bucket.drop().await?;

Para obtener más información sobre cualquiera de los métodos o tipos mencionados en esta guía, consulta la siguiente documentación API:

Volver

Buscar geoespacialmente

En esta página