我运行一个运行在nodeJS + mongoDB后端的网站。现在,我正在实现一个系统来存储需要在数据库中的一些图标(小图像文件)。
根据我的理解,不使用GridFS更有意义,因为它似乎是为大文件或大量文件量身定制的。由于我需要保存的每个文件都在BSON最大文件大小之下,我应该能够将它们直接保存到常规文档中。
我有两个问题:
1)我的推理是否正确?将图像文件保存在常规mongo集合中是否可以,而不是使用GridFS?我有什么不考虑的吗?
2)如果我的思维过程合理,我该怎么做呢?我可以做类似以下的事情:
//assume 'things' is a mongoDB collection created properly using node-mongodb-driver
fs.readFile(pathToIconImage, function(err,image){
things.insert({'image':image}, function(err,doc){
if(err) console.log('you have an error! ' + err);
});
});
我猜这可能有更好的方法,因为mongoDB使用BSON,在这里我试图在将数据发送到数据库之前用JSON保存文件。我也不知道这段代码是否有效(没试过)。
更新 - 新问题
如果我在一个集合中有一个文件,其中保存了三条信息:1)名称,2)日期,3)图像文件(上图标),我想将此文件发送给客户端为了显示这三个,这可能吗?如果没有,我想我需要使用GridFS并保存fileID来代替图像本身。想法/建议?
最好,感谢任何回复,
萨米
答案 0 :(得分:25)
如果您的图片确实小到不会出现文档大小问题,并且您不介意进行一些额外的处理,那么将它直接存储在您的收藏中可能会很好。为此,您需要对图像进行base64编码,然后使用mongo的BinData类型进行存储。据我了解,然后将其保存为BSON位数组,而不是实际存储base64字符串,因此大小不会比原始二进制图像大。
它将在json查询中显示为base64字符串,您可以使用它来获取二进制图像。
答案 1 :(得分:5)
我一直在寻找同样的事情。 我知道这篇文章很老了,但也许我可以帮助那些人。
var fs = require('fs');
var mongo = require('mongodb').MongoClient;
var Binary = require('mongodb').Binary;
var archivobin = fs.readFileSync("vc.exe");
// print it out so you can check that the file is loaded correctly
console.log("Loading file");
console.log(archivobin);
var invoice = {};
invoice.bin = Binary(archivobin);
console.log("largo de invoice.bin= "+ invoice.bin.length());
// set an ID for the document for easy retrieval
invoice._id = 12345;
mongo.connect('mongodb://localhost:27017/nogrid', function(err, db) {
if(err) console.log(err);
db.collection('invoices').insert(invoice, function(err, doc){
if(err) console.log(err);
// check the inserted document
console.log("Inserting file");
console.log(doc);
db.collection('invoices').findOne({_id : 12345}, function(err, doc){
if (err) {
console.error(err);
}
fs.writeFile('vcout.exe', doc.bin.buffer, function(err){
if (err) throw err;
console.log('Sucessfully saved!');
});
});
});
});