1. Libros y videos
  2. MongoDB
  3. Gestionar archivos binarios usando GridFS
Extrait - MongoDB Comprensión y optimización de la gestión de datos (con ejercicios y soluciones)
Extractos del libro
MongoDB Comprensión y optimización de la gestión de datos (con ejercicios y soluciones) Volver a la página de compra del libro

Gestionar archivos binarios usando GridFS

Introducción

MongoDB incluye un mecanismo integrado para gestionar archivos binarios de más de 16 megabytes: su nombre es GridFS.

¿Cómo funciona?

GridFS funciona dividiendo un archivo muy grande en varios trozos (chunks), que en realidad son documentos con un tamaño predefinido de 255 kilobytes. GridFS es una especie de capa de gestión de archivos sobre MongoDB, que solo funciona con documentos.

Aunque la razón de ser de GridFS es ayudar a almacenar archivos de gran tamaño, como archivos de audio o vídeo, nada impide utilizarlo con archivos de cualquier tamaño o naturaleza (texto puro, por ejemplo), incluidos archivos más pequeños que los 255 kilobytes que conforman el tamaño predefinido de un chunk. Por supuesto, prácticamente no tiene sentido utilizarlo de esta forma, ya que GridFS sigue teniendo capacidad para archivos de más de 16 megabytes, pero puede considerarse, como veremos en el ejemplo siguiente, por razones prácticas. Si el archivo que se quiere almacenar es menor de 16 megabytes, es mejor utilizar el tipo BinData, que almacena la información en forma de cadenas de caracteres binarios codificadas en base64.

GridFS puede tener ventajas sobre la lectura desde el sistema de archivos, que sigue siendo más competitiva en términos de tiempo de ejecución:

  • No hay límite en el número de archivos que pueden almacenarse, como puede ocurrir a veces en los directorios de un sistema de archivos (varía entre unos cientos de miles y varios millones)....

Colecciones de chunks y archivos

GridFS se basa en dos colecciones para gestionar estos archivos de gran tamaño: la primera, llamada chunks (pedazo, trozo), aloja los documentos que componen el archivo, mientras que la segunda, llamada files, contiene los metadatos asociados al archivo. En los chunks, encontraremos el número de secuencia del trozo del archivo y su contenido en forma binaria (BSON, ¿quién si no?) y en los files, información como la fecha de descarga, el tamaño de cada chunk del archivo o el nombre del archivo dividido en varios trozos.

Estas colecciones necesitan ser indexadas y estos índices son creados automáticamente por los controladores si se está usando MongoDB desde cualquier lenguaje de desarrollo moderno. Sin embargo, si se opera, como lo hemos estado haciendo, desde el shell, puede que necesite crearlos usted mismo usando los siguientes comandos:

db.fs.chunks.createIndex( { files_id: 1, n: 1 }, { unique: true } ) 
db.fs.files.createIndex( { filename: 1, uploadDate: 1 } ) 

Estas dos colecciones se pueden fragmentar si se desea: para los chunks, la clave de fragmentación (shard) puede estar formada por el campo files_id, posiblemente vinculado a otro campo, mientras que para files la clave de fragmentación puede estar formada por el campo _id solo o vinculado a otro campo.

Utilizar mongofiles

El programa mongofiles, que se suministra de serie con todas las distribuciones de MongoDB y es autocontenido porque no se utiliza desde el shell, permite interactuar con la base de datos muy fácilmente. Encontrará este ejecutable en el directorio de instalación.

1. Añadir un archivo a GridFS

El comando mongofiles se puede utilizar para agregar un archivo a GridFS, y su sintaxis es muy simple:

mongofiles put < ruta del archivo > 

Vamos a crear un archivo de texto rudimentario y agregarlo (la respuesta del programa está en negritas):

echo "Mongofiles de prueba" > /tmp/archivoPequeño.txt   
mongofiles put /tmp/archivoPequeño.txt  
connected to: mongodb://localhost/  
adding gridFile: /tmp/archivoPequeño.txt  
added gridFile: /tmp/archivoPequeño.txt 

El archivo ha sido añadido. Utilicemos ahora el shell para comprobar su presencia en cada una de las colecciones gestionadas por GridFS. Primero, en la colección chunks, cuyo espacio de nombres (namespace) completo es db.fs.chunks:

db.fs.chunks.find()  
[  
  {  
    _id: ObjectId("65d481d5fed024efe9bf1ba5"),  
    files_id: ObjectId("65d481d5fed024efe9bf1ba4"),  
    n: 0,  
    data: Binary(Buffer.from("54657374204d6f6e676f66696c65730a",  
"hex"), 0)  
  }  
] 

El valor del campo n nos indica que este único chunk...