GridFS 是 MongoDB 中用于存储大型文件的一种机制,适用于需要存储大量二进制数据的场景,例如视频、音频、图片等。在本文中,我们将深入探讨 MongoDB 中 GridFS 文件存储的相关知识,并提供示例代码和实际案例。
GridFS 的基本概念
GridFS 旨在解决 MongoDB 单文档大小限制(16MB)的问题,它实现了文件的分块存储,把一个大的文件分成多个块(Chunk),每个块的大小默认是 255K,最多可以设置为 64MB,然后将块存储到 MongoDB 的多个文档中。在存储过程中,GridFS 会自动管理这些块的排序和重组。
GridFS 集合包括两个部分:
files
集合保存文件的元数据信息,如文件名、大小、类型、上传时间和 chunkSize 等。chunks
集合保存文件的二进制数据块,按照files_id
字段关联到files
集合中的文件。
GridFS 的用途
由于 MongoDB 的单文档容量有限,因此如果想存储大型文件,如图片、视频等,需要采用 GridFS 进行存储。GridFS 可以有效地解决文件的上传、下载、删除等需求。此外,GridFS 还具有以下优势:
- 处理大型文件更方便。GridFS 可以自动将大型文件拆分成多个 chunk 存储,更易于处理大型文件。
- 支持分布式存储。MongoDB 可以自动将大型数据划分成多个块,并将这些块存储在整个集群的多个节点上,以实现更好的伸缩性和容错性。
- 支持灵活的查询。GridFS 可以支持查询和选择文件的任意块,这比传统文件系统更灵活,更易于处理非结构化数据。
- 支持元数据扩展。GridFS 可以在文件存储中存储更多的元数据信息,例如存储有关文件作者、描述等信息,为文件管理提供更多的灵活性和可操作性。
GridFS 的操作
上传文件
使用 GridFS 上传文件需要先将文件读入内存,然后将其转化为二进制数据块并逐个插入到 chunks
集合中。最后,将文件的元数据信息插入到 files
集合中。
下面是一个示例代码:
// javascriptcn.com 代码示例 const mongodb = require('mongodb'); const { MongoClient } = mongodb; // 创建一个 MongoClient const client = new MongoClient('mongodb://localhost:27017', { useNewUrlParser: true }); // 连接 MongoDB 服务器 client.connect(async (err) => { if (err) throw err; try { // 数据库和集合名称 const dbName = 'test'; const bucketName = 'avatars'; // 获取 GridFSBucket 对象 const db = client.db(dbName); const bucket = new mongodb.GridFSBucket(db, { bucketName }); // 读取文件内容 const content = await fs.promises.readFile('./avatar.png'); // 插入文件数据到 GridFS const uploadStream = bucket.openUploadStream('avatar.png'); await stream.pipeline( Readable.from(content), uploadStream ); // 输出上传的文件 ID console.log('File uploaded with ID:', uploadStream.id); } catch (err) { console.error(err); } finally { // 断开连接 client.close(); } });
下载文件
使用 GridFS 下载文件首先需要获取文件的元数据信息,然后使用 openDownloadStream()
方法打开读取数据流,并使用 Node.js 流操作将文件流写入文件或响应中。可以使用文件的 _id
或文件名来下载文件。
下面是一个示例代码:
// javascriptcn.com 代码示例 const mongodb = require('mongodb'); const { MongoClient } = mongodb; // 创建一个 MongoClient const client = new MongoClient('mongodb://localhost:27017', { useNewUrlParser: true }); // 连接 MongoDB 服务器 client.connect(async (err) => { if (err) throw err; try { // 数据库和集合名称 const dbName = 'test'; const bucketName = 'avatars'; // 获取 GridFSBucket 对象 const db = client.db(dbName); const bucket = new mongodb.GridFSBucket(db, { bucketName }); // 下载文件数据 const downloadStream = bucket.openDownloadStreamByName('avatar.png'); const content = await streamToBuffer(downloadStream); // 将文件写入到文件中 await fs.promises.writeFile('./avatar.png', content); } catch (err) { console.error(err); } finally { // 断开连接 client.close(); } });
删除文件
使用 GridFS 删除文件需要先删除 chunks
集合中的所有块,然后再删除 files
集合中的元数据信息。
下面是一个示例代码:
// javascriptcn.com 代码示例 const mongodb = require('mongodb'); const { MongoClient } = mongodb; // 创建一个 MongoClient const client = new MongoClient('mongodb://localhost:27017', { useNewUrlParser: true }); // 连接 MongoDB 服务器 client.connect(async (err) => { if (err) throw err; try { // 数据库和集合名称 const dbName = 'test'; const bucketName = 'avatars'; // 获取 GridFSBucket 对象 const db = client.db(dbName); const bucket = new mongodb.GridFSBucket(db, { bucketName }); // 删除文件数据 const file = await db.collection('fs.files').findOne({ filename: 'avatar.png' }); await db.collection('fs.chunks').deleteMany({ files_id: file._id }); await db.collection('fs.files').deleteOne({ _id: file._id }); console.log('File deleted successfully.'); } catch (err) { console.error(err); } finally { // 断开连接 client.close(); } });
总结
GridFS 是 MongoDB 中存储大型文件的重要机制,它能够有效地解决单文档大小限制问题,支持分布式存储,在处理大型数据和非结构化数据方面也更加灵活和高效。本文介绍了 GridFS 的基本概念、用途和操作,希望对大家理解 MongoDB 的文件存储机制有所帮助。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/6528d3fd7d4982a6ebb613a8