Docs Menu
Docs Home
/ /

GridFS

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

Utilice GridFS si el tamaño de su archivo supera el límite de tamaño de documento BSON de 16 MB. GridFS también le permite acceder a los archivos sin cargarlos completamente en la memoria. Para obtener información más detallada sobre si GridFS es adecuado para su caso de uso, consulte 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 buckets contienen las siguientes colecciones, nombradas según la convención definida en la especificación de GridFS:

  • chunks, que almacena los fragmentos de archivos binarios

  • 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 de depósito predeterminado 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

Puede crear una referencia a un bucket de GridFS siguiendo los pasos de la sección "Hacer referencia a un bucket de GridFS" de esta página. Sin embargo, el controlador no crea un nuevo bucket de GridFS ni sus índices hasta la primera operación de escritura. Para obtener más información sobre los índices de GridFS, consulte la página "Índices de GridFS" del manual del servidor.

Al almacenar un archivo en un depósito GridFS, el controlador 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 de la colección chunks que almacenan el contenido del archivo, que el controlador 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 depósito especificado y utiliza la información para reconstruir el archivo a partir de los documentos de la colección chunks. Puede leer el archivo en memoria o exportarlo a una secuencia.

Antes de almacenar archivos en un depósito GridFS, cree una referencia de depósito u obtenga una referencia a un depósito existente.

El siguiente ejemplo llama al método gridfs_bucket() en una instancia de base de datos, que crea una referencia a un depósito 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

Instanciación de estructuras

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

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 del fragmento utilizado para dividir el archivo en fragmentos, que es 255 KB de manera predeterminada.

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 subir un archivo a un bucket de GridFS abriendo un flujo de carga y escribiendo el archivo en él. Llama al método open_upload_stream() en la instancia de tu bucket para abrir el flujo. Este método devuelve una instancia de GridFsUploadStream donde puedes escribir el contenido del archivo. Para subir el contenido del archivo a 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 un depósito 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 el atributo futures_io::AsyncRead. Para usar los métodos de lectura AsyncRead, como read_to_end(), importe el módulo AsyncReadExt al archivo de su 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 (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 del bucket de GridFS para recuperar archivos del bucket. El método devuelve una instancia de cursor desde la que se puede 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 derecuperación de datos. Para obtener más información sobre cómo recuperar datos de un cursor, consulte la guía "Acceder a datos mediante un cursor".

Puedes actualizar el nombre de un archivo GridFS en tu bucket llamando al método rename() en una instancia del bucket. Pasa el valor _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 eliminar un archivo de tu bucket. Para ello, llama a delete() en la instancia de tu bucket y pasa el valor _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 depósito 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, consulte la siguiente documentación de API:

Volver

Buscar geoespacialmente

En esta página