使用 Mongoose 模式将大型 blob 数据保存到 GridFS

Saving large blob data to GridFS using Mongoose schema

我正在尝试制作一个将在 LAN 上使用的幻灯片 Web 应用程序,因此加载时间应该不是一个大问题。

我已经使用 angular-fullstack 生成了我的锅炉镀层。

我查看了一些解决方案并找到了 mongoose-fs,这似乎是我正在寻找的功能。但我似乎无法让它发挥作用。我通读了源代码,一切似乎都有意义。

问题出在我的 post API 中,尽管 req.body 有 req.body.music,其中包含一个大的 22MB mp3,幻灯片变量 Slide.create 没有 slide.music 属性.

我是否遗漏了什么或者是否有更好的解决方案来将大文件保存到 GridFS?

这是我的模式

"use strict";

var mongoose = require("mongoose");
var mongooseFS = require("mongoose-fs");
var Schema = mongoose.Schema;

var SlideSchema = new Schema({
    name: String,
    info: String,
    imgData: Buffer,
    interval: Number
});

var SlideCollection = new Schema({
    name: String,
    slideshow: [SlideSchema]
});

SlideCollection.plugin(mongooseFS, {keys: ["music"]});

module.exports = mongoose.model("Slide", SlideCollection);

我的控制器 POST API 看起来像这样

// Creates a new slide in the DB.
exports.create = function(req, res) {
    Slide.create(req.body, function(err, slide) {
        if(err) { return handleError(res, err); }
        return res.status(201).json(slide);
    });
};

我无法让 mongoose-fs 工作,但我发现 mongoose-gridstore 它基于 mongoose-fs 并且似乎足够简单(或者至少有足够的文档记录)供我使用.我不得不重写我的 POST API 以使其工作,但到目前为止,它提供了我想要的功能,即上传大型 mp3。

我也想要一个更动态的模式来处理上传大图像,但我认为 16mb 的限制现在是可行的。

这就是我的架构现在的样子。

"use strict";

var mongoose = require("mongoose");
var gridStore = require("mongoose-gridstore");
var Schema = mongoose.Schema;

var SlideSchema = new Schema({
    name: String,
    info: String,
    imgData: String,
    interval: Number
});

var SlideCollection = new Schema({
    name: String,
    slideshow: [SlideSchema]
});

SlideCollection.plugin(gridStore);

module.exports = mongoose.model("Slide", SlideCollection);

这是新的 POST API

// Creates a new slide in the DB.
exports.create = function(req, res) {
    var slide = new Slide({
        name: req.body.name,
        slideshow: req.body.slideshow
    });

    slide.addAttachment(req.body.name, String(req.body.music))
        .catch( function(err) { handleError(res, err); } );

    slide.save(function(err, post) {
        if(err) { return handleError(res, err); }

        return res.status(201).json(post);
    });
};

为了完整起见,这里也是 GET

// Get a single slide
exports.show = function(req, res) {
    Slide.findById(req.params.id, function (err, slide) {
        if(err) { return handleError(res, err); }
        if(!slide) { return res.status(404).send("Not Found"); }
        slide.loadAttachments()
            .then(function(doc) {
                return res.json(doc);
            })
            .catch(function(loadingErr) {
                throw loadingErr;
            });
    });
};

然后在 Angular 中,我需要获取 response.attachements[0].buffer 来访问二进制数据以执行我需要的操作。