Javascript 无法将缓冲区写入MongoDB GridFS
嗨,伙计们,我花了将近一天的时间试图弄明白这一点。我正在使用multer的inMemory标志从我的网页上载图像。显而易见的尝试是将从multer接收到的缓冲区写入GridFs(更具体地说是GridStore) 这是我的密码 product.js(路线/控制器) 我的DB对象来自哪里?我只是在初始化过程中将其添加到mongoose对象中。这就是代码的样子 database.jsJavascript 无法将缓冲区写入MongoDB GridFS,javascript,node.js,mongodb,express,gridfs,Javascript,Node.js,Mongodb,Express,Gridfs,嗨,伙计们,我花了将近一天的时间试图弄明白这一点。我正在使用multer的inMemory标志从我的网页上载图像。显而易见的尝试是将从multer接收到的缓冲区写入GridFs(更具体地说是GridStore) 这是我的密码 product.js(路线/控制器) 我的DB对象来自哪里?我只是在初始化过程中将其添加到mongoose对象中。这就是代码的样子 database.js var mongoose = require("mongoose"), mongooseTimestamps
var mongoose = require("mongoose"),
mongooseTimestamps = require("mongoose-concrete-timestamps"),
autoIncrement = require("mongoose-auto-increment"),
config = require("../config"),
Grid = require("gridfs-stream");
mongoose.connect( config.database['development'].url + "" + config.database['development'].name );
var db = mongoose.connection;
db.once("open", function(err){
if(err) throw err
mongoose.GridStore = mongoose.mongo.GridStore
})
db.on("error",function(errMsg){
console.log("Error Connecting to Mongo: " + errMsg);
});
mongoose.set('debug', true);
mongoose.plugin(mongooseTimestamps);
autoIncrement.initialize(db);
module.exports = mongoose;
因此,在无数次更改代码并得到相同的结果后,这就是我目前所做的——没有写入,没有错误
我每次都从猫鼬的输出日志中得到这个
POST /product/1000/images 200 4.494 ms - 22
Mongoose: fs.chunks.ensureIndex([ [ 'files_id', 1 ], [ 'n', 1 ] ]) { w: 'majority' }
Mongoose: fs.files.find({ filename: '2b08f506ed277eda45f9fc400c098aa1.jpg' }) { readPreference: 'primary', w: 'majority' }
Mongoose: fs.chunks.find({ n: 0, files_id: ObjectId("54bb87aaabf2c0416a50c068") }) { readPreference: 'primary', w: 'majority' }
如果我错了,请纠正我,但为什么在我“插入/写入”GridFS时它会执行查找。到目前为止,我得到了这个输出,我的断点只得到了对GridStore.open的调用,我正确地返回了流,但是写入从未发生,也没有抛出错误
到目前为止我都试过了
非常感谢您的帮助。现在,您错过的是“inMemory”选项中的“buffer”不是“非此即彼”,也不意味着内容被保存在“内存”中。它实际上是数据的“副本”,也被发送到磁盘上的临时文件 因此,设置“inMemory”与否并不重要,因为仍将创建文件(默认情况下在
/tmp
目录中),但当超出范围时,这些文件当然将取消链接:
var async = require('async'),
express = require('express'),
multer = require('multer'),
fs = require('fs'),
mongoose = require('mongoose'),
Grid = require('gridfs-stream'),
Schema = mongoose.Schema;
Grid.mongo = mongoose.mongo;
var app = express(),
gfs = {};
// Set up multer middleware
app.use(
multer({
//inMemory: true
})
);
// Register handler
app.post('/',function (req,res) {
async.eachLimit(Object.keys(req.files), 10, function(file,callback) {
var fileobj = req.files[file];
var writeStream = gfs.createWriteStream({
"filename": fileobj.fieldname
});
fs.createReadStream(fileobj.path).pipe(writeStream);
writeStream.on('close',function() {
console.log('done');
callback();
});
writeStream.on('error',callback);
},function(err) {
if (err) {
console.log(err);
res.status(500).end();
}
res.status(200).end();
});
});
mongoose.connect('mongodb://localhost/test');
// Start app listen and events
var server = app.listen(3000,function() {
mongoose.connection.on('open',function(err) {
if (err) throw err;
// Set up connection
gfs = Grid(mongoose.connection.db);
console.log('listening and connected');
});
});
当然还有一个简单的测试:
var FormData = require('form-data'),
fs = require('fs'),
http = require('http');
var fname = 'GearsLogo.png';
var form = new FormData();
form.append(fname,fs.createReadStream(fname))
var request = http.request({
method: 'post',
port: 3000,
headers: form.getHeaders()
});
form.pipe(request);
request.on('response',function(res) {
console.log(res.statusCode);
});
或者根据您的请求方法调用中间件,和/或设置
onFileUploadComplete()
处理程序,而不是迭代req.files
的内容。“gridfs=stream”软件包可能是上传内容的最简单的选项,而尝试从副本缓冲区工作并不会带来任何真正的优势,因为IO成本和存储总是存在的。我认为Multer在使用“inMemory”选项时不会向fs写入任何内容。我已经分析了源代码,如果我看得正确,它只在inMemory未设置为true时写入。(请参见第118行)但您是对的,files.buffer只是所有传入数据片段的副本,可能会导致非常慢的性能。因此,写入磁盘应该更快
var FormData = require('form-data'),
fs = require('fs'),
http = require('http');
var fname = 'GearsLogo.png';
var form = new FormData();
form.append(fname,fs.createReadStream(fname))
var request = http.request({
method: 'post',
port: 3000,
headers: form.getHeaders()
});
form.pipe(request);
request.on('response',function(res) {
console.log(res.statusCode);
});