使用 gridfs 和 mongoose 在 mongodb 中存储文件

Posted

技术标签:

【中文标题】使用 gridfs 和 mongoose 在 mongodb 中存储文件【英文标题】:storing files in mongodb using gridfs and mongoose 【发布时间】:2013-10-27 17:39:17 【问题描述】:

我有以下代码

gridfs.js 具有以下写入文件字节的代码

exports.putFile = function(path, name, options, fn) 
    var db;
    db = mongoose.connection.db;
    options = parse(options);
    options.metadata.filename = name;
    return new GridStore(db, name, "w", options).open(function(err, file) 
        if (err) 
            return fn(err);
        
        return file.writeFile(path, fn);
    );
;

猫鼬模式定义如下。 mongoose 架构具有文件名和文件本身。

var fs = require('fs');
var mongoose = require('mongoose');
var db = mongoose.connection;
var gridfs = require('./gridfs');
var Schema = mongoose.Schema;

var trackDocsSchema = mongoose.Schema(
        
            _id : Schema.Types.ObjectId,
            docName: 'string',
            files: [ mongoose.Schema.Mixed ]
        
);

trackDocsSchema.methods.addFile = function(file, options, fn) 
    var trackDocs;
    trackDocs = this;
    return gridfs.putFile(file.path, file.name, options, function(err, result) 
        if (err) console.log("postDocsModel TrackDocs Error: " + err);

        trackDocs.files.push(result);
        return trackDocs.save(fn);
    );
;

var TrackDocs = mongoose.model("TrackDocs", trackDocsSchema);

调用的服务器代码如下。

exports.uploadFile = function (req, res) 
    console.log("uploadFile invoked");
          var trackDocs, opts;
        trackDocs = new TrackDocs();
        trackDocs._id = mongoose.Types.ObjectId(req.body._id);
        trackDocs.docName = req.body.docName;
        opts = 
            content_type: req.files.file.type
        ;

        return trackDocs.addFile(req.files.file, opts, function (err, result) 
            if (err) console.log("api TrackDocs Error: " + err);

            console.log("Result: " + result);
            trackDocs.save();
            console.log("Inserted Doc Id: " + trackDocs._id);
            return res.json(true);
        );
    ;
);

当我运行以下代码时,我得到一个错误

api TrackDocs 错误:RangeError:超出最大调用堆栈大小,并且没有任何内容添加到 GridFS。但是,如果我再次上传相同的文件,它确实会将其保存到 GridFS 中。

注意有两个 trackDocs.saves。我不确定这是导致问题还是其他原因。

我是 NodeJS 和 Mongoose 的新手,因此我们将不胜感激。

谢谢, 梅尔罗伊

【问题讨论】:

你有什么收获吗? 哪一行抛出异常?一种潜在的解决方法(不是真正的解决方案)是增加堆栈大小。您可以在调用脚本时执行此操作node --stack-size=32000 app.js 您如何处理文件上传?使用强大的库或其他一些库? 您的问题解决了吗?我需要做类似的事情,在 Mongo 中存储二进制文件。 【参考方案1】:

不确定这是否有帮助,但过去曾帮助过我。

毫不奇怪,不同的浏览器有不同的调用堆栈大小。同样不足为奇的是,他们用来确定调用堆栈的方法也各不相同。我可以测量的各种调用堆栈大小是(给或取,可能相差 1 或 2):

我们自己进行了一些测试,以便使用以下简单代码获取其他浏览器/主机/操作系统上的调用堆栈大小:

var i = 0;

function recurse () 
    i++;
    recurse();


try 
    recurse();
 catch (ex) 
    alert('i = ' + i + '\nerror: ' + ex);

http://javascriptrules.com/2009/06/30/limitation-on-call-stacks/

说一个选项可以将--max-stack-size 传递给节点。

设置最大 v8 堆栈大小(字节)

node --max-stack-size 32000 app.js

注意:帮助将其打印为--max-stack-size,在node -v v0.10.x+ 你需要使用--stack-size 代替。

【讨论】:

以上是关于使用 gridfs 和 mongoose 在 mongodb 中存储文件的主要内容,如果未能解决你的问题,请参考以下文章

如何从 GridFS 中的块和文件中删除文件?

MongoDB GridFS

如何使用gridFs将我的后端与我的前端与angular2和ionic2连接起来?

在 Angular 中从 Mongoose 下载文件

如何使用 React 前端从 Mongoose 显示带有 <img> 的图像

如何在使用 gridfs 保存之前调整大小和图像?