Javascript 无法将缓冲区写入MongoDB GridFS

Javascript 无法将缓冲区写入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

嗨,伙计们,我花了将近一天的时间试图弄明白这一点。我正在使用multer的inMemory标志从我的网页上载图像。显而易见的尝试是将从multer接收到的缓冲区写入GridFs(更具体地说是GridStore)

这是我的密码

product.js(路线/控制器)

我的DB对象来自哪里?我只是在初始化过程中将其添加到mongoose对象中。这就是代码的样子

database.js

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的调用,我正确地返回了流,但是写入从未发生,也没有抛出错误

到目前为止我都试过了

  • 使用Multer的InMemory-相同的结果
  • 使用Multer的dest属性并将流从fs传输到gridfs-结果相同
  • 使用gridfs流模块-相同的结果
  • 使用本机GridFS/GridStoire-结果相同

  • 非常感谢您的帮助。

    现在,您错过的是“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);
    });