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
/ /

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 PyMongo 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.

Deberías usar GridFS si el tamaño de tus archivos excede 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 MongoDB Server.

Las siguientes secciones describen las operaciones de GridFS y cómo realizarlas.

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 chunks la colección almacena los fragmentos de archivos binarios.

  • La colección files almacena los metadatos del archivo.

Cuando crees un nuevo bucket GridFS, el driver creará las colecciones anteriores, prefijadas con el nombre de bucket por defecto fs, a menos que indiques un nombre diferente. El controlador también crea un índice en cada colección para asegurar la recuperación eficiente de los archivos y metadatos relacionados. El driver crea el cubo GridFS, si no existe, solo cuando se realiza la primera operación de guardado. El controlador crea índices solo si no existen y cuando el cubo está vacío. Para más información sobre los índices de GridFS, consulta Índices GridFS en el manual de MongoDB Server.

Al almacenar archivos con GridFS, 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 files colección que contiene un ID de archivo, nombre de archivo y otros metadatos del archivo. Puedes cargar el archivo desde la memoria o desde un flujo. Consulta el siguiente diagrama para ver cómo GridFS divide los archivos al cargarlos en 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.

Para almacenar o recuperar archivos de GridFS, cree un bucket de GridFS llamando al constructor GridFSBucket() y pasando una instancia Database. Puedes utilizar la instancia GridFSBucket para llamar operaciones de lectura y escritura sobre los archivos de tu bucket. Si está trabajando con una aplicación asíncrona, use el constructor AsyncGridFSBucket() en su lugar.

Selecciona el Synchronous o la pestaña Asynchronous para ver el código correspondiente:

client = MongoClient("<connection string>")
db = client["db"]
bucket = gridfs.GridFSBucket(db)
client = AsyncMongoClient("<connection string>")
db = client["db"]
bucket = gridfs.AsyncGridFSBucket(db)

Para crear o referenciar un bucket con un nombre personalizado distinto del predeterminado fs, pase el nombre del bucket como segundo parámetro al constructor GridFSBucket(), como se muestra en el siguiente ejemplo. Seleccione la pestaña Synchronous o Asynchronous para ver el código correspondiente:

custom_bucket = gridfs.GridFSBucket(db, bucket_name="myCustomBucket")
custom_bucket = gridfs.AsyncGridFSBucket(db, bucket_name="myCustomBucket")

Utiliza el método open_upload_stream() de la clase GridFSBucket para crear un flujo de carga para un nombre de archivo dado. El método open_upload_stream() permite especificar información de configuración, como el tamaño de los fragmentos del archivo y otros pares campo/valor para almacenar como metadatos. Establezca estas opciones como parámetros de open_upload_stream(), como se muestra en el siguiente ejemplo de código. Selecciona la pestaña Synchronous o Asynchronous para ver el código correspondiente:

with bucket.open_upload_stream(
"my_file", chunk_size_bytes=1048576, metadata={"contentType": "text/plain"}
) as grid_in:
grid_in.write("data to store")
async with bucket.open_upload_stream(
"my_file", chunk_size_bytes=1048576, metadata={"contentType": "text/plain"}
) as grid_in:
await grid_in.write("data to store")

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 cualquier otra información

Para recuperar archivos de un bucket de GridFS, llama al método find() en la instancia GridFSBucket. El método devuelve una instancia de Cursor desde la que puede acceder a los resultados. Para aprender más sobre Cursor objetos en PyMongo, consulte Accede a los datos desde un cursor.

El siguiente ejemplo de código muestra cómo recuperar e imprimir los metadatos de archivos de todos sus archivos en un depósito GridFS. Utiliza la sintaxis for...in para recorrer el iterable Cursor y mostrar los resultados. Selecciona la pestaña Synchronous o Asynchronous para ver el código correspondiente:

for file_doc in bucket.find({}):
print(file_doc)
async for file_doc in bucket.find({}):
print(file_doc)

El método find() acepta varias especificaciones de query. Puedes usar sus parámetros para especificar el criterio de ordenación, el número máximo de documentos que se van a devolver y el número de documentos que se van a omitir antes de la devolución. Para aprender a consultar MongoDB, consulta Encontrar documentos.

Puedes descargar archivos de tu base de datos MongoDB utilizando el método open_download_stream_by_name() de GridFSBucket para crear una secuencia de descarga.

El siguiente ejemplo muestra cómo descargar un archivo referenciado por el nombre de archivo, "my_file", y leer su contenido. Selecciona la pestaña Synchronous o Asynchronous para ver el código correspondiente:

file = bucket.open_download_stream_by_name("my_file")
contents = file.read()
file = await bucket.open_download_stream_by_name("my_file")
contents = await file.read()

Nota

Si hay varios documentos con el mismo valor filename, GridFS transmitirá el archivo más reciente con el nombre dado (según lo determinado por el campo uploadDate).

Como alternativa, puede usar el método open_download_stream(), que toma el campo _id de un archivo como parámetro. Seleccione la pestaña Synchronous o Asynchronous para ver el código correspondiente:

file = bucket.open_download_stream(ObjectId("66b3c86e672a17b6c8a4a4a9"))
contents = file.read()
file = await bucket.open_download_stream(ObjectId("66b3c86e672a17b6c8a4a4a9"))
contents = await file.read()

Nota

La API de transmisión de GridFS no puede cargar fragmentos parciales. Cuando una secuencia de descarga necesita obtener un fragmento de MongoDB, lo carga completo en la memoria. El tamaño de fragmento por defecto de 255kilobytes suele ser suficiente, pero puedes reducir el tamaño de los fragmentos para disminuir la sobrecarga de memoria.

Utiliza el método rename() para actualizar el nombre de un archivo GridFS en su bucket. Debes especificar el archivo que deseas renombrar por su campo _id en lugar de su nombre de archivo.

El siguiente ejemplo muestra cómo actualizar el campo filename a "new_file_name" haciendo referencia al campo _id de un documento. Selecciona la pestaña Synchronous o Asynchronous para ver el código correspondiente:

bucket.rename(ObjectId("66b3c86e672a17b6c8a4a4a9"), "new_file_name")
await bucket.rename(ObjectId("66b3c86e672a17b6c8a4a4a9"), "new_file_name")

Nota

El método rename() solo admite la actualización del nombre de un archivo a la vez. Para cambiar el nombre de varios archivos, recupere una lista de archivos que coincidan con el nombre de archivo desde el bucket, extraiga el campo _id de los archivos a los que desea cambiar el nombre y pase cada valor en llamadas por separado al método rename().

Utilice el método delete() 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 haciendo referencia a su campo _id. Seleccione la pestaña Synchronous o Asynchronous para ver el código correspondiente:

bucket.delete(ObjectId("66b3c86e672a17b6c8a4a4a9"))
await bucket.delete(ObjectId("66b3c86e672a17b6c8a4a4a9"))

Nota

El método delete() solo soporta borrar un archivo a la vez. Para borrar varios archivos, recuperar los archivos del bucket, extraiga el campo _id de los archivos que desea borrar y pase cada valor en llamadas separadas al método delete().

Para obtener más información sobre el uso de PyMongo para almacenar y recuperar archivos grandes, consulte la siguiente documentación de API:

Volver

Transacciones

En esta página