当前位置:  开发笔记 > 编程语言 > 正文

如何使用GridFS使用Node.js和Mongoose存储图像

如何解决《如何使用GridFS使用Node.js和Mongoose存储图像》经验,为你挑选了3个好方法。

我是Node.js的新手.任何人都可以提供一个如何使用GridFS来存储和检索使用Node.js和Mongoose的二进制数据(如图像)的示例吗?我需要直接访问GridFS吗?



1> Mitja..:

我对这里评价最高的答案不满意,所以我提供了一个新答案:我最终使用节点模块 'gridfs-stream'(那里有很棒的文档!),可以通过npm安装.有了它,并与猫鼬结合,它可能看起来像这样:

var fs = require('fs');
var mongoose = require("mongoose");
var Grid = require('gridfs-stream');
var GridFS = Grid(mongoose.connection.db, mongoose.mongo);

function putFile(path, name, callback) {
    var writestream = GridFS.createWriteStream({
        filename: name
    });
    writestream.on('close', function (file) {
      callback(null, file);
    });
    fs.createReadStream(path).pipe(writestream);
}

请注意,path是本地系统上文件的路径.

至于我的文件读取功能,对于我的情况我只需要将文件流式传输到浏览器(使用快递):

try {
    var readstream = GridFS.createReadStream({_id: id});
    readstream.pipe(res);
} catch (err) {
    log.error(err);
    return next(errors.create(404, "File not found."));
}



2> Riky_Tree..:

到目前为止答案是好的,但是,我认为在此处记录如何使用官方mongodb nodejs驱动程序而不是依赖于诸如"gridfs-stream"之类的进一步抽象将是有益的.

之前的一个答案确实使用了官方mongodb驱动程序,但他们使用的是Gridstore API; 这已经被弃用了,请看这里.我的示例将使用新的GridFSBucket API.

问题是相当广泛的,因为我的答案将是一个完整的nodejs程序.这将包括设置快速服务器,mongodb驱动程序,定义路由以及处理GET和POST路由.

使用Npm包

表达(nodejs Web应用程序框架以简化此代码段)

multer(用于处理multipart/form-data请求)

mongodb(官方mongodb nodejs驱动程序)

GET照片路径将Mongo ObjectID作为参数来检索图像.

我配置multer以将上传的文件保存在内存中.这意味着照片文件不会随时写入文件系统,而是直接从内存流式传输到GridFS.


/**
 * NPM Module dependencies.
 */
const express = require('express');
const photoRoute = express.Router();

const multer = require('multer');
var storage = multer.memoryStorage()
var upload = multer({ storage: storage, limits: { fields: 1, fileSize: 6000000, files: 1, parts: 2 }});

const mongodb = require('mongodb');
const MongoClient = require('mongodb').MongoClient;
const ObjectID = require('mongodb').ObjectID;
let db;

/**
 * NodeJS Module dependencies.
 */
const { Readable } = require('stream');

/**
 * Create Express server && Routes configuration.
 */
const app = express();
app.use('/photos', photoRoute);

/**
 * Connect Mongo Driver to MongoDB.
 */
MongoClient.connect('mongodb://localhost/photoDB', (err, database) => {
  if (err) {
    console.log('MongoDB Connection Error. Please make sure that MongoDB is running.');
    process.exit(1);
  }
  db = database;
});

/**
 * GET photo by ID Route
 */
photoRoute.get('/:photoID', (req, res) => {
  try {
    var photoID = new ObjectID(req.params.photoID);
  } catch(err) {
    return res.status(400).json({ message: "Invalid PhotoID in URL parameter. Must be a single String of 12 bytes or a string of 24 hex characters" }); 
  }

  let bucket = new mongodb.GridFSBucket(db, {
    bucketName: 'photos'
  });

  let downloadStream = bucket.openDownloadStream(photoID);

  downloadStream.on('data', (chunk) => {
    res.write(chunk);
  });

  downloadStream.on('error', () => {
    res.sendStatus(404);
  });

  downloadStream.on('end', () => {
    res.end();
  });
});

/**
 * POST photo Route
 */
photoRoute.post('/', (req, res) => {
  upload.single('photo')(req, res, (err) => {
    if (err) {
      return res.status(400).json({ message: "Upload Request Validation Failed" });
    } else if(!req.body.name) {
      return res.status(400).json({ message: "No photo name in request body" });
    }

    let photoName = req.body.name;

    // Covert buffer to Readable Stream
    const readablePhotoStream = new Readable();
    readablePhotoStream.push(req.file.buffer);
    readablePhotoStream.push(null);

    let bucket = new mongodb.GridFSBucket(db, {
      bucketName: 'photos'
    });

    let uploadStream = bucket.openUploadStream(photoName);
    let id = uploadStream.id;
    readablePhotoStream.pipe(uploadStream);

    uploadStream.on('error', () => {
      return res.status(500).json({ message: "Error uploading file" });
    });

    uploadStream.on('finish', () => {
      return res.status(201).json({ message: "File uploaded successfully, stored under Mongo ObjectID: " + id });
    });
  });
});

app.listen(3005, () => {
  console.log("App listening on port 3005!");
});

我写了一篇关于这个主题的博客文章; 是我的答案的详细说明.可在这里

进一步阅读/启发:

NodeJs Streams:你需要知道的一切

Multer NPM文档

Nodejs MongoDB驱动程序



3> blockchainde..:

我建议看一下这个问题:MongoDB GridFS使用Node.JS保存文件的问题

从答案中复制的例子(信用转到christkv):

// You can use an object id as well as filename now
var gs = new mongodb.GridStore(this.db, filename, "w", {
  "chunk_size": 1024*4,
  metadata: {
    hashpath:gridfs_name,
    hash:hash,
    name: name
  }
});

gs.open(function(err,store) {
  // Write data and automatically close on finished write
  gs.writeBuffer(data, true, function(err,chunk) {
    // Each file has an md5 in the file structure
    cb(err,hash,chunk);
  });
});


我正在努力解决上面例子中的this.db部分; 我不确定如何从Mongoose获取MongoDB数据库对象.
推荐阅读
360691894_8a5c48
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有