GridFS en MongoDB: almacenar archivos grandes | Nicolás Garzón
Texto
Copiar archivo
→ fs.files: metadata
→ fs.chunks: partes ordenadasPor defecto, un bucket usa colecciones como fs.files y fs.chunks, aunque el nombre puede configurarse.
GridFS puede ser adecuado cuando:
los archivos deben versionarse y replicarse junto con MongoDB;
se necesita streaming desde el driver;
no existe object storage disponible;
la autorización y metadata viven cerca de los datos;
los archivos superan el límite de documento;
el workload se beneficia de backups y topología MongoDB comunes.
No debe elegirse solo porque la aplicación ya utiliza MongoDB.
S3, Cloud Storage o servicios equivalentes suelen ser mejores para:
CDN y distribución pública;
archivos muy grandes;
multipart upload especializado;
lifecycle tiers;
URLs firmadas;
costes de almacenamiento masivo;
replicación geográfica especializada;
procesamiento multimedia.
JavaScript
Copiar {
objectKey : 'businesses/123/invoices/abc.pdf' ,
contentType : 'application/pdf' ,
size : 184230 ,
checksum : '...' ,
createdAt
} MongoDB conserva metadata; el binario vive en object storage.
TypeScript
Copiar const bucket = new GridFSBucket ( db, {
bucketName: 'documents'
} ) ;
const upload = bucket. openUploadStream ( 'invoice.pdf' , {
metadata: {
businessId,
ownerId,
contentType: 'application/pdf'
}
} ) ;
sourceStream. pipe ( upload) ; Maneja errores en ambos streams y espera la finalización antes de confirmar al cliente.
TypeScript
Copiar const download = bucket. openDownloadStream ( fileId) ;
download. on ( 'error' , handleError) ;
download. pipe ( response) ; Aplica autorización antes de abrir el stream. No confíes únicamente en conocer el ObjectId.
Contiene filename, length, chunk size, upload date y metadata.
Cada documento almacena una parte y su posición n. Un índice unique protege la combinación de file ID y posición.
La aplicación no debe insertar chunks manualmente salvo que implemente correctamente todo el protocolo; utiliza el driver.
Durante una subida incompleta pueden existir chunks sin un archivo final visible o metadata parcial según el punto del fallo. La aplicación necesita cleanup de uploads abandonados y una política de estado.
JavaScript
Copiar {
status : 'uploading' | 'ready' | 'failed' ,
gridFsFileId,
expiresAt
} Confirma ready solo después de completar el stream.
Guarda checksum para verificar contenido:
Texto
Copiar stream recibido
→ calcular SHA-256
→ almacenar hash
→ verificar en descarga o migraciónNo uses hashes débiles como garantía de seguridad. La versión exacta del driver puede no calcular automáticamente el checksum que necesita tu dominio.
GridFS permite múltiples archivos con el mismo filename. No uses filename como identidad única. Conserva un ID de dominio y una versión:
JavaScript
Copiar metadata : {
documentId,
version : 3 ,
businessId
} Un índice propio o colección de metadata puede definir la versión activa.
GridFS soporta acceso por rangos mediante APIs compatibles, útil para media o reanudación. Sin embargo, un CDN u object storage suele ofrecer mejor distribución para tráfico masivo.
Los chunks se replican como datos MongoDB, aumentando:
tamaño del oplog;
backups;
initial sync;
cache pressure;
red entre miembros;
coste de sharding.
Un archivo de 1 GB no se vuelve gratuito por dividirse en chunks.
GridFS puede utilizarse en entornos sharded bajo reglas y diseño específicos. Analiza shard keys, targeting de chunks, distribución de archivos grandes y compatibilidad del driver. No fragmentes un archivo sin comprender cómo se enrutan todos sus chunks.
valida MIME real, no solo extensión;
limita tamaño;
analiza malware cuando corresponda;
aplica tenant scope;
cifra tránsito y almacenamiento;
evita ejecución inline de contenido peligroso;
usa Content-Disposition seguro;
no expongas metadata sensible;
define retención y borrado.
Eliminar un archivo debe retirar metadata y chunks mediante API del bucket:
TypeScript
Copiar await bucket. delete ( fileId) ; Una eliminación parcial manual puede dejar orphans. Audita también referencias desde documentos de dominio y backups.
Upload se corta a mitad.
Cliente repite la misma subida.
Filename contiene caracteres no confiables.
Archivo tiene MIME falsificado.
Se elimina metadata de dominio pero no GridFS.
Restore recupera chunks sin referencias actuales.
Descarga se cancela y el stream queda abierto.
Un archivo enorme degrada oplog window.
guardar un archivo grande como Binary normal;
usar GridFS como CDN;
cargar todo con toArray o buffer;
no limitar tamaño;
autorizar por file ID únicamente;
insertar chunks manualmente;
no limpiar uploads fallidos;
olvidar impacto en backups y replication.
Sube archivos vacíos, pequeños y grandes.
Interrumpe el upload.
Cancela descargas.
Verifica checksum.
Prueba autorización multi-tenant.
Ejecuta delete.
Busca orphans.
Mide memoria y streaming.
Prueba backup/restore.
Compara costes con object storage.
GridFS integra archivos con MongoDB mediante chunks y streaming, pero transfiere el coste a replication, backups y almacenamiento del cluster. Es correcto cuando esa integración aporta valor; para distribución masiva, CDN y lifecycle avanzado, object storage suele ser mejor.
Comprueba lo aprendido
¿Qué colecciones utiliza GridFS?
¿Por qué no usar filename como identidad?
¿Qué ocurre si un upload falla a mitad?
¿Qué ventaja tiene streaming?
¿Cuándo preferir object storage?
¿Cómo eliminarías un archivo correctamente?