如何将GridStore替换为GridFSBucket?

12

我收到了这个错误信息:

(node:11976) DeprecationWarning: GridStore is deprecated, and will be removed in a future version. Please use GridFSBucket instead

有时候我在查看图片的时候遇到了问题,我猜是因为文档不够详细,所以我不知道如何将代码切换到GridFSBucket,以下是我的代码:

and sometimes I have trouble viewing the picture , I guess because of that, due to poor documentation I have no idea how to switch my code to GridFSBucket, this is it:

conn.once("open", () => {
  // Init stream
  gfs = Grid(conn.db, mongoose.mongo);
  //gfs = new mongoose.mongo.GridFSBucket(conn.db);
  gfs.collection("user_images");
});


var storageImage = new GridFsStorage({
  url: dbURI,
  options: { useNewUrlParser: true, useUnifiedTopology: true },
  file: (req, file) => {
    return new Promise((resolve, reject) => {
      crypto.randomBytes(16, (err, buf) => {
        if (err) {
          return reject(err);
        }
        const filename = buf.toString("hex") + path.extname(file.originalname);
        const fileInfo = {
          filename: filename,
          bucketName: "user_images"
        };
        resolve(fileInfo);
      });
    });
  }
});
const uploadImage = multer({ storage: storageImage });

    const uploadImage = multer({ storage: storageImage });
router.get("/image/:filename", (req, res) => {
  gfs.files.findOne({ filename: req.params.filename }, (err, file) => {
    if (!file || file.length === 0) {
      return res.status(404).json({
        err: "No file exists"
      });
    }

    if (file.contentType === "image/jpeg" || file.contentType === "image/png") {
      const readstream = gfs.createReadStream(file.filename);
      //const readstream = gridFSBucket.openUploadStream(file.filename);
      readstream.pipe(res);
    } else {
      res.status(404).json({
        err: "Not an image"
      });
    }
  });
});

我非常感激您的帮助,请问我需要在这里做出哪些改变,以便与GridFsBucket一起使用?非常感谢!


您说的“查看图片有问题”,是指在 HTML 表单中预览时出现问题?还是在下载后导致错误? - Sheece Gardazi
3个回答

2

我最终遇到了同样的问题,你很可能已经确定readstream = gfs.createReadStream(file.filename); 正是导致错误的原因。只需要添加一个新变量并更改一行代码即可。

//add var
let gridFSBucket;
let gfs;
connection.once('open', () => {
  gfs = Grid(conn.db, mongoose.mongo);
  // add value to new var
  gridFSBucket = new mongoose.mongo.GridFSBucket(conn.db, {
    bucketName: 'user_images'
  });

  gfs = Grid(connection.db, mongoose.mongo);
  gfs.collection(image_bucket_name);

  if (file.contentType === 'image/jpeg' || file.contentType === 'image/png') {
    //now instead of const readstream = gfs.createReadStream(file.filename);
    //add this line
    const readStream = gridFSBucket.openDownloadStream(file._id);
    readSteam.pipe(res);
  }
});

如果你遇到了(DeprecationWarning: GridStore已被弃用,将在未来的版本中删除。请使用GridFSBucket代替),希望这可以为你节省一些时间。


2

虽然我来晚了,但是由于我也遇到了相同的问题,现有的答案并不能解决这个问题,所以我将分享我找到的解决方法,以便未来有人遇到同样的问题时能够参考:

// Old Way:
const conn = mongoose.createConnection(youConnectionURI);
const gfs = require('gridfs-store')(conn.db);
gfs.collection('yourBucketName');

// New Way:
const conn = mongoose.createConnection(youConnectionURI);
const gridFSBucket = new mongoose.mongo.GridFSBucket(conn.db, {bucketName: 'yourBucketName'});

如果您想了解如何使用GridFSBucket执行CRUD操作,请查看此页面此页面


0
我按照这个教程创建了这个配方。教程非常棒,它很好地解释了所有的步骤。完整的代码示例可以在这里找到。
HTML表单示例:
<form action="http://localhost:4000/upload" method="post" enctype="multipart/form-data">
      <input type="file"  name='image' />
      <button type="submit" >Submit</button>
</form>

上传图片到mongodb的控制器代码:

const path = require('path');
const crypto = require('crypto');
const mongoose = require('mongoose');
const multer = require('multer');
const GridFsStorage = require('multer-gridfs-storage');
const Grid = require('gridfs-stream');

const mongodbURL="mongodb+srv://<user>:<pass>@cluster.mongodb.net/<databaseName>"
const connection = mongoose.createConnection(mongoURI);

// Init gfs
let gfs;
const image_bucket_name = "user_images"

connection.once('open', () => {
    // Init stream
    gfs = Grid(connection.db, mongoose.mongo);
    gfs.collection(image_bucket_name);
})

// Create storage engine
const storage = new GridFsStorage({
    url: mongoURI,
    file: (req, file) => {
        return new Promise((resolve, reject) => {
            crypto.randomBytes(16, (error, buffer) => {
                if (error) {
                    return reject(error);
                }
                const filename = buffer.toString('hex') + path.extname(file.originalname);
                const fileinfo = {
                    filename: filename,
                    bucketName: image_bucket_name
                };
                resolve(fileinfo);
            })
        });
    }
});

const upload = multer({ storage });
app.post('/upload', upload.single('image'), async (req, res) => {
    console.log("uploaded image: "+req.file.
});

这个答案使用了gridfs-stream包,这也导致了错误的发生。 - Nikitas IO
@Inhinito 你试过这个解决方案吗?它抛出了什么错误? - Sheece Gardazi
您提出的解决方案使用了已弃用的GridFS包,如果不更新到GridFSBucket包,则会引发弃用警告。 - Nikitas IO

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接