Overview
En esta guía, puedes aprender cómo almacenar y recuperar archivos grandes en MongoDB utilizando la especificación GridFS. GridFS divide los archivos grandes en fragmentos y almacena cada fragmento como un documento separado. Cuando usted query GridFS por un archivo, el driver ensambla los fragmentos según sea necesario. La implementación del driver de GridFS es una abstracción que gestiona las operaciones y la organización del almacenamiento de archivos.
Utiliza GridFS si el tamaño de tus archivos supera el límite de tamaño de documentos BSON de 16 MB. GridFS también te ayuda a acceder a archivos sin cargar el archivo completo en la memoria. Para obtener información más detallada sobre si GridFS es adecuado para su caso de uso, consulte el Página de manual del servidor GridFS.
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:
La
chunkscolección, que almacena los fragmentos de archivos binarios.La colección
files, que almacena los metadatos del archivo.
Cuando creas un nuevo bucket GridFS, el driver crea las colecciones anteriores. El nombre de bucket por defecto fs antepone los nombres de las colecciones, a menos que se especifique un nombre de bucket diferente. El driver crea el nuevo contenedor GridFS durante la primera operación de guardar.
El controlador también crea un índice en cada colección para garantizar la recuperación eficiente de los archivos y los metadatos relacionados. El controlador crea índices si aún no existen y cuando el depósito está vacío. Para obtener más información sobre los índices de GridFS, consulta la página del manual del servidor sobre Índices de GridFS.
Al almacenar archivos con GridFS, el driver divide los archivos en fragmentos más pequeños, cada uno representado por un documento aparte en la colección chunks. También crea un documento en la colección files que contiene un ID de archivo, el nombre del archivo y otros metadatos del archivo. El siguiente diagrama muestra cómo GridFS divide los archivos cargados:

Al recuperar archivos, GridFS obtiene los metadatos de la colección files en el bucket especificado, y luego utiliza esa información para reconstruir el archivo a partir de los documentos en la colección chunks. Puedes leer el archivo en memoria o sacarlo a un flujo.
Utilice GridFS
Para aprender sobre las operaciones de GridFS y cómo ejecutarlas, navega a las siguientes secciones:
Crear un bucket de GridFS
Para almacenar o recuperar archivos de GridFS, crea un bucket de almacenamiento o consigue una referencia a un bucket de almacenamiento existente en una base de datos MongoDB. Para crear una instancia de GridFSBucket, llame al método NewBucket() con un parámetro de base de datos:
db := client.Database("db") bucket, err := gridfs.NewBucket(db) if err != nil { panic(err) }
Nota
Si ya existe un cubo de GridFS, el método NewBucket() devuelve una referencia al cubo en lugar de crear una nueva instancia.
Por defecto, el nuevo bucket se llama fs. Para instanciar un bucket con un nombre personalizado, llama al método SetName() en una instancia de BucketOptions de la siguiente manera:
db := client.Database("db") opts := options.GridFSBucket().SetName("custom name") bucket, err := gridfs.NewBucket(db, opts) if err != nil { panic(err) }
Cargar archivos
Puedes subir un archivo a un bucket GridFS de alguna de las siguientes maneras:
Utiliza el método
UploadFromStream(), que lee desde un flujo de entrada.Utiliza el método
OpenUploadStream(), que escribe en un flujo de salida.
Para cualquiera de los procesos de carga, puedes especificar información de configuración en una instancia de UploadOptions. Para ver una lista completa de los campos UploadOptions, visita la documentación de la API.
Carga con una secuencia de entrada
Para cargar un archivo con un flujo de entrada, utiliza el método UploadFromStream() con los siguientes parámetros:
El nombre de tu archivo
Un
io.Reader, con tu archivo abierto como parámetroUn parámetro opcional
optspara modificar el comportamiento deUploadFromStream()
El siguiente ejemplo de código lee un archivo llamado file.txt y sube el contenido a un bucket GridFS. Utiliza un parámetro opts para establecer los metadatos del archivo:
file, err := os.Open("path/to/file.txt") uploadOpts := options.GridFSUpload().SetMetadata(bson.D{{"metadata tag", "first"}}) objectID, err := bucket.UploadFromStream("file.txt", io.Reader(file), uploadOpts) if err != nil { panic(err) } fmt.Printf("New file uploaded with ID %s", objectID)
New file uploaded with ID 62e00...
Carga con un flujo de salida
Para cargar un archivo con un flujo de salida, use el método OpenUploadStream() con los siguientes parámetros:
El nombre de tu archivo
Un parámetro opcional
optspara modificar el comportamiento deOpenUploadStream()
El siguiente ejemplo de código abre un flujo de subida en un bucket GridFS y establece el número de bytes en cada fragmento con un parámetro opts. Luego, llama al método Write() sobre el contenido de file.txt para guardar su contenido en el flujo:
file, err := os.Open("path/to/file.txt") if err != nil { panic(err) } // Defines options that specify configuration information for files // uploaded to the bucket uploadOpts := options.GridFSUpload().SetChunkSizeBytes(200000) // Writes a file to an output stream uploadStream, err := bucket.OpenUploadStream("file.txt", uploadOpts) if err != nil { panic(err) } fileContent, err := io.ReadAll(file) if err != nil { panic(err) } var bytes int if bytes, err = uploadStream.Write(fileContent); err != nil { panic(err) } fmt.Printf("New file uploaded with %d bytes written", bytes) // Calls the Close() method to write file metadata if err := uploadStream.Close(); err != nil { panic(err) }
Recuperar información de archivos
Puedes recuperar los metadatos del archivo almacenados en la colección files del bucket GridFS. Cada documento de la colección files contiene la siguiente información:
El ID del archivo
La longitud del archivo
El tamaño máximo de fragmento
La fecha y hora de carga
El nombre del archivo
Un documento
metadataen el que puedes almacenar cualquier otra información
Para recuperar los datos de un archivo, invoca el método Find() en una instancia de GridFSBucket. Puedes pasar un filtro de query como argumento a Find() para que solo coincida con ciertos documentos de archivos.
Nota
El método Find() requiere un filtro de query como parámetro. Para hacer coincidir todos los documentos en la colección files, pase un filtro de query vacío a Find().
El siguiente ejemplo recupera el nombre del archivo y la longitud de los documentos en la colección files con valores de length superiores a 1500:
filter := bson.D{{"length", bson.D{{"$gt", 1500}}}} cursor, err := bucket.Find(filter) if err != nil { panic(err) } type gridfsFile struct { Name string `bson:"filename"` Length int64 `bson:"length"` } var foundFiles []gridfsFile if err = cursor.All(context.TODO(), &foundFiles); err != nil { panic(err) } for _, file := range foundFiles { fmt.Printf("filename: %s, length: %d\n", file.Name, file.Length) }
Descargar archivos
Puedes descargar un archivo GridFS de una de las siguientes maneras:
Utiliza el método
DownloadToStream()para descargar un archivo en un stream de salida.Use el método
OpenDownloadStream()para abrir un flujo de entrada.
Descargar un archivo a un flujo de salida
Puedes descargar un archivo en un bucket de GridFS directamente a un stream de salida utilizando el método DownloadToStream(). DownloadToStream() acepta como parámetros un ID de archivo y un io.Writer. El método descarga el archivo con el ID de archivo especificado y lo escribe en el io.Writer.
El siguiente ejemplo descarga un archivo y guarda en un búfer de archivos:
id, err := primitive.ObjectIDFromHex("62f7bd54a6e4452da13b3e88") fileBuffer := bytes.NewBuffer(nil) if _, err := bucket.DownloadToStream(id, fileBuffer); err != nil { panic(err) }
Descargar un archivo en un flujo de entrada
Puedes descargar un archivo de un bucket GridFS a la memoria con una secuencia de entrada usando el método OpenDownloadStream(). OpenDownloadStream() recibe un ID de archivo como parámetro y devuelve un flujo de entrada del que puedes leer el archivo.
El siguiente ejemplo descarga un archivo en la memoria y lee su contenido:
id, err := primitive.ObjectIDFromHex("62f7bd54a6e4452da13b3e88") downloadStream, err := bucket.OpenDownloadStream(id) if err != nil { panic(err) } fileBytes := make([]byte, 1024) if _, err := downloadStream.Read(fileBytes); err != nil { panic(err) }
Renombrar archivos
Puedes actualizar el nombre de un archivo de GridFS en tu bucket usando el método Rename(). Pasa un valor de ID de archivo y un nuevo valor de filename como argumentos a Rename().
El siguiente ejemplo renombra un archivo a "mongodbTutorial.zip":
id, err := primitive.ObjectIDFromHex("62f7bd54a6e4452da13b3e88") if err := bucket.Rename(id, "mongodbTutorial.zip"); err != nil { panic(err) }
Borrar archivos
Puedes remover un archivo de tu bucket de GridFS usando el método Delete(). Pase un valor de ID de archivo como argumento a Delete().
El siguiente ejemplo elimina un archivo:
id, err := primitive.ObjectIDFromHex("62f7bd54a6e4452da13b3e88") if err := bucket.Delete(id); err != nil { panic(err) }
Borrar un bucket de GridFS
Puede borrar un bucket GridFS utilizando el método Drop().
El siguiente ejemplo de código elimina un bucket de GridFS:
if err := bucket.Drop(); err != nil { panic(err) }
Recursos adicionales
Para obtener más información sobre GridFS y sus operaciones, visita la página del manual de GridFS.
Documentación de la API
Para aprender más sobre los métodos o tipos estudiados en esta guía, consulta la siguiente Documentación de la API: