Consejos Tecnológicos

¿Qué es GridFS en MongoDB?

Muchas aplicaciones utilizan la gestión de archivos y el almacenamiento de archivos como elementos clave para mejorar el procesamiento de datos. El almacenamiento de archivos a menudo implica el uso de CDN (redes de entrega de contenido) de terceros, como Amazon Web Services, aunque esto puede complicar la administración. Es mejor acceder a todos los recursos desde una única ubicación de almacenamiento en la nube, en lugar de varias ubicaciones diferentes, porque el proceso de recuperación puede fallar.

Antes de que se agregara GridFS a MongoDB, era difícil almacenar archivos directamente en la base de datos mediante una sola solicitud de API. Descubra cómo GridFS utiliza índices y almacena datos en tamaños pequeños para acelerar la recuperación y las formas de lograr este objetivo. Explore los beneficios y las limitaciones de usar GridFS.

¿Qué es GridFS?

GridFS es una especificación de controlador para cargar y recuperar archivos de MongoDB. Es una especificación para almacenar y recuperar archivos que superen el límite de 16 MB de documentos BSON. Divide el archivo en varias partes o bloques y guarda cada bloque como un documento separado en lugar de almacenar el archivo como un solo documento.

El tamaño de cada bloque solo puede ser de 255 KB. Esto significa que el bloque final suele ser igual o inferior a 255 KB. ¡Eso es genial!

GridFS es una tecnología adecuada para almacenar archivos en MongoDB, que complementa la recuperación de información no modal (y por lo tanto más rápida) proporcionada por el modelo de documento.

Debido a que el archivo está dividido en partes más pequeñas, es más fácil acceder a áreas específicas del archivo, lo que ahorra tareas que consumen mucha memoria, como cargar el archivo completo.

Al leer de GridFS, el controlador vuelve a ensamblar todos los bloques según sea necesario. Esto significa que puede leer bloques de archivos, escuchar fragmentos de archivos de audio o recuperar fragmentos de videoclips según el alcance de la consulta.

Colección GridFS Índice MongoDB GridFS

Para mejorar la eficiencia, GridFS usa índices en cada bloque y colección de archivos. Para mayor comodidad, los controladores que siguen la especificación GridFS crearán automáticamente estos índices.

La especificación define una API GridFS simple. La especificación también describe las características avanzadas de GridFS que los controladores pueden optar por proporcionar en su implementación. Además, este trabajo tiene como objetivo definir el significado y el propósito de todos los campos en el modelo de datos GridFS, eliminar ambigüedades en la nomenclatura GridFS y registrar opciones de configuración no especificadas previamente. También puede agregar tantos índices como necesite para satisfacer las necesidades de su aplicación.

Índice de bloque

GridFS usa los campos files_id yn para crear un índice compuesto único en la colección de bloques. Esto permite una recuperación de bloques eficiente, como se muestra en el siguiente ejemplo:

db.fs.chunks.find( { files_id: myFileID } ).sort( { n: 1 } )

Los controladores que siguen la especificación GridFS comprobarán automáticamente si este índice existe antes de realizar operaciones de lectura y escritura. Para obtener información sobre el comportamiento único de la aplicación GridFS, consulte la documentación del controlador correspondiente.

Si este índice no existe, puede ejecutar la siguiente operación para crearlo usando MongoDB Shell (mongosh). Este es un entorno REPL completo de JavaScript y Node.js 14.x para manejar la implementación de MongoDB. Puede usar MongoDB Shell para probar directamente consultas y operaciones en su base de datos.

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

Índice de archivo

Utiliza el índice de la colección de archivos según el nombre del archivo y la columna UploadDate. Puede lograr una recuperación de archivos eficiente, como se muestra en el siguiente ejemplo:

db.fs.files.find( { filename: myFileName } ).sort( { uploadDate: 1 } )

Si este índice aún no existe, puede usar el shell mongo para construirlo:

db.fs.files.createIndex( { filename: 1, uploadDate: 1 } );

Los controladores que siguen la especificación GridFS comprobarán automáticamente si este índice existe antes de realizar operaciones de lectura y escritura. Para obtener información sobre el comportamiento único de la aplicación GridFS, consulte la documentación del controlador correspondiente.

Fragmentación de MongoDB GridFS

GridFS se divide en dos colecciones: archivos y bloques.

Colección de bloques

El bloque almacena bloques binarios.Utilizar cualquiera {files_id: 1, n: 1} o {ID de archivo: 1}Como índice de clave de fragmentación para fragmentar la colección de bloques. files_id es un ObjectId que se actualiza monótonamente.

Si el controlador MongoDB usa filemd5, no se puede usar la fragmentación de hash.

Cada documento de la colección de fragmentos representa un fragmento único del archivo en GridFS. Los documentos de esta colección están en el siguiente formato:

{ 
  "_id" : <ObjectId>, 
  "files_id" : <ObjectId>, 
  "n" : <num>, 
  "data" : <binary> 
}

Los siguientes campos se incluyen en algunos o en todos los documentos de la colección de bloques:

chunks._id: ObjectId único.
chunks.files_id: En la colección de archivos, podemos especificar el _id del documento principal.
chunks.n: el número de secuencia del fragmento. GridFS asigna un número a cada bloque, comenzando desde 0.
chunks.data: como la carga útil de los fragmentos de tipo binario BSON.

Colección de archivos

«Archivo» almacena los metadatos del archivo. La colección de archivos es la más pequeña y se compone principalmente de metadatos. Las claves GridFS no son adecuadas para una distribución justa en un sistema de fragmentación. Esto permite que todos los registros de metadatos de archivos residan en un solo segmento maestro.

Si necesita dividir una colección de archivos, use el campo _id asociado con el campo de la aplicación.

Cada documento de la colección de archivos representa un archivo en GridFS.

{
  "_id" : <ObjectId>,
  "length" : <num>,
  "chunkSize" : <num>,
  "uploadDate" : <timestamp>,
  "md5" : <hash>,
  "filename" : <string>,
  "contentType" : <string>,
  "aliases" : <string array>,
  "metadata" : <any>,
}

Los siguientes campos se incluyen en algunos o en todos los documentos de la colección de archivos:

files.length: el tamaño del documento (en bytes).

files._id: _id es el tipo de datos que especificó cuando creó el documento original. BSON ObjectId es el tipo predeterminado de documentos MongoDB.

files.chunkSize: el tamaño de cada fragmento (en bytes). Excepto por el último bloque, es solo el tamaño requerido y GridFS divide el documento en trozos de tamaño chunkSize. El tamaño estándar es de 255 kilobytes (kB).

files.uploadDate: almacenamiento inicial de documentos de GridFS. El tipo de valor es fecha.

files.md5: el comando filemd5 devuelve el valor hash MD5 de todo el archivo. Es de tipo cuerda.

files.metadata: el campo de metadatos puede contener cualquier tipo de datos y cualquier información adicional que elija almacenar. Si desea agregar campos más arbitrarios a los documentos de la colección de archivos, agréguelos al objeto de metadatos.

files.aliases: una matriz de cadenas de alias.

files.contentType: es completamente opcional. El tipo MIME aplicable a los archivos GridFS.

files.filename: es completamente opcional. El nombre legible por humanos del archivo GridFS.

ejemplo:

{
"_id" : ObjectId("6177da181964fd7f82e2aaa9"),
"length" : 15720,
"chunkSize" : 261120,
"uploadDate" : ISODate("2021-10-26T16:06:08.091+05:30"),
"filename" : "ishanfile.docx",
"contentType" : "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
}

La colección de archivos es la misma que la colección de bloques, utilizando un índice compuesto basado en el nombre del archivo y la columna de fecha de carga para lograr una recuperación de archivos eficiente, por ejemplo:

db.fs.files.find( { filename: fileName } ).sort( { uploadDate: 1 } )

Si este índice no existe, ejecute el siguiente comando en el shell de mongo:

db.gfs.file.createIndex( { filename: 1, uploadDate: 1 }, { unique: true } );

Esto hará que el resultado sea:

¿Cómo leer y escribir archivos en MongoDB GridFS?

Para estudiar más a fondo este tutorial, su máquina debe tener instalado el siguiente software:

  • Node.js
  • Brújula MongoDB y MongoDB
  • Código VS

paso 1: Cree una carpeta llamada mongo_grid. Inicie el editor de VSCode y navegue hasta esta carpeta. Esta carpeta se convertirá en un espacio de trabajo que contiene todos los archivos de código que contiene.

Paso 2: En este espacio de trabajo, cree carpetas denominadas archivos para leer y archivos para escribir, que contendrán los archivos que se leerán y guardarán en la base de datos, así como los archivos que se leerán de la base de datos.

Paso 3: Abra el terminal VS Code y ejecute npm init -y

Este comando creará un archivo de espacio de trabajo package.json con ciertas secciones preestablecidas.

Utilice los siguientes comandos para instalar gridfs-stream y mongoose:

npm install gridfs-stream
npm install mongoose

En la sección devDependencies Package.jsonArchivo, que define los siguientes paquetes:

¿Qué es GridFS en MongoDB?

El paquete gridfs-stream le permite transferir fácilmente archivos desde y hacia MongoDB GridFS. El paquete mongoose contiene una herramienta de modelado de objetos MongoDB, que está diseñada para ejecutarse en un entorno asincrónico para operar en bases de datos MongoDB.

Etapa 4: Mantenga la siguiente estructura de carpetas del proyecto:

¿Qué es GridFS en MongoDB?

Coloque algunas imágenes / videos / audios en la carpeta filetoread. Estos archivos se utilizarán para actividades de escritura y lectura. En este ejemplo, se utiliza un archivo gfs.png de muestra.

Paso 5: Abra MongoDB Compass y conéctese a la base de datos MongoDB. Cree una base de datos llamada filesDB y una colección llamada files.

Paso 6: Para escribir un archivo en GridFS, cree un archivo javascript y asígnele el nombre writefile.js y escriba el siguiente código en el archivo:

//1. Load the mongoose driver
var mongooseDv = require("mongoose");
//2. Connect to MongoDB and its database
mongooseDv.connect('mongodb://localhost/filesDB', { useMongoClient: true });
//3. The Connection Object
var connection = mongooseDv.connection;
if (connection !== "undefined") {
    console.log(connection.readyState.toString());
    //4. The Path object
    var path = require("path");
    //5. The grid-stream
    var grid = require("gridfs-stream");
    //6. The File-System module
    var fs = require("fs");
    //7.Read the video/image file from the videoread folder
    var filesrc = path.join(__dirname, "./filestoread/gfs.png");
    //8. Establish connection between Mongo and GridFS
    grid.mongo = mongooseDv.mongo;
    //9.Open the connection and write file
    connection.once("open", () => {
        console.log("Connection Open");
        var gridfs = grid(connection.db);
        if (gridfs) {
            //9a. create a stream, this will be
            //used to store file in database
            var streamwrite = gridfs.createWriteStream({
                //the file will be stored with the name
                filename: "gfs.png"
            });
            //9b. create a readstream to read the file
            //from the filestored folder
            //and pipe into the database
            fs.createReadStream(filesrc).pipe(streamwrite);
            //9c. Complete the write operation
            streamwrite.on("close", function (file) {
                console.log("successfully written in database");
            });
        } else {
            console.log("No Grid FS Object");
        }
    });
} else {
    console.log('Not connected');
}
console.log("done");

Los archivos de la carpeta filestoread se proporcionan como parámetros para la función createReadStream () del módulo fs. La función pipe () acepta el flujo de escritura formado por el objeto gridfs. Esta secuencia está destinada a utilizarse con archivos de imagen.

Paso 7: Ejecute el código usando Archivo de escritura de nodo

Esto proporcionará el siguiente resultado:

¿Qué es GridFS en MongoDB?

Ahora verifique MongoDB Compass, los datos en filesDB se verán así:

¿Qué es GridFS en MongoDB?

Usted puede documento:

¿Qué es GridFS en MongoDB?

Paso 8: Para leer el archivo, cree un archivo javascript y asígnele un nombre Leer file.js:

var mongooseDv = require("mongoose");
var schema = mongooseDv.Schema;
mongooseDv.connect('mongodb://localhost/filesDB', { useMongoClient: true });
var connection = mongooseDv.connection;
if (connection !== "undefined") {
    console.log(connection.readyState.toString());
    var path = require("path");
    var grid = require("gridfs-stream");
    var fs = require("fs");
    var videosrc = path.join(__dirname, "./filestowrite/videos.mp4");
    grid.mongo = mongooseDv.mongo;
    connection.once("open", () => {
        console.log("Connection Open");
        var gridfs = grid(example.db);
        if (gridfs) {
            var fsstreamwrite = fs.createWriteStream(
                path.join(__dirname, "./filestowrite/gfs.png")
            );
            var readstream = gridfs.createReadStream({
                filename: "gfs.png"
            });
            readstream.pipe(fsstreamwrite);
            readstream.on("close", function (file) {
                console.log("File Read successfully from database");
            });
        } else {
            console.log("No Grid FS Object");
        }
    });
} else {
    console.log(Not connected');
}
console.log("done");

Paso 9: Use el nodo para ejecutar el código anterior Leer archivo

Esto proporcionará el siguiente resultado:

¿Qué es GridFS en MongoDB?

Esto leerá el archivo de MongoDB GridFS y lo escribirá en la carpeta filestowrite:

¿Qué es GridFS en MongoDB?

Cuándo usar el sistema de almacenamiento MongoDB GridFS

El sistema de almacenamiento MongoDB GridFS no se usa mucho, pero pueden ser necesarias las siguientes condiciones:

  • Cuando el sistema de archivos actual tiene un límite en la cantidad de archivos que se pueden almacenar en un directorio determinado.
  • Cuando solo necesita acceder a la parte guardada de la información, GridFS le permite llamar a varias partes del archivo sin tener que verificar todo el documento.
  • Al distribuir archivos y sus metadatos a través de conjuntos de réplicas distribuidos geográficamente, GridFS permite que los metadatos se sincronicen e implementen automáticamente entre varios equipos de destino.

Cuándo no usar el sistema de almacenamiento MongoDB GridFS

Si necesita actualizar el contenido de todo el archivo, no debe usar GridFS. Como alternativa, puede conservar varias copias de cada archivo y especificar la última versión en los metadatos. Después de cargar la nueva versión del archivo, puede usar actualizaciones atómicas para actualizar los campos de metadatos que indican el estado «más reciente» y luego eliminar la versión anterior si es necesario.

Si todos sus archivos son más pequeños que el límite de tamaño de documento BSON de 16 MB, considere almacenar cada archivo en un solo documento en lugar de utilizar GridFS. Para almacenar datos binarios, puede utilizar el tipo de datos BinData. Para obtener más información sobre el uso de BinData, consulte la documentación de su controlador.

Limitaciones de MongoDB GridFS

El sistema de archivos GridFS tiene las siguientes limitaciones:

  • La entrega de archivos junto con el contenido de la base de datos puede agotar gravemente su conjunto de trabajo de RAM. Si no desea destruir su conjunto de trabajo, debe servir sus archivos desde un servidor mongodb diferente.
  • El rendimiento del servicio de archivos será más lento que el de servir archivos localmente desde su servidor web y sistema de archivos. Sin embargo, las ganancias adicionales de la gestión pueden superar la desaceleración.
  • GridFS no admite actualizaciones de archivos atómicos. Si esto sucede, deberá conservar varias versiones del archivo y elegir la versión adecuada.

El poder y el auge de GridFS

GridFS es un regalo para los desarrolladores que desean almacenar archivos grandes en MongoDB. El sistema de almacenamiento GridFS permite a los desarrolladores almacenar archivos grandes y recuperar algunos de estos archivos según sea necesario. Por lo tanto, GridFS es una característica excelente de MongoDB que se puede utilizar en varias aplicaciones. El beneficio real de este método es que puede leer solo una parte del archivo en lugar de cargar el archivo completo en la memoria. Esto hace que GridFS sea una herramienta muy útil para aplicaciones modernas.

Publicaciones relacionadas

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Botón volver arriba