错误:grid.mongo.GridStore不是构造函数,使用mongoose、Grid-fs-stream和grid multer存储

问题描述 投票:0回答:5

我收到以下提到的错误。 基本配置如下: 我已经将文件上传到服务器上 我想下载它们但出现这些错误 我向 /api/files/delete/${fileId} 调用了 POST 请求 它应该调用路由并将文件返回给浏览器,而不是使用网格相关模块获取错误。

MONGODB_CONNECTION_STRING = mongodb://localhost:27017/Cstore

Db structure={Cstore:{uploads.files,uploads.chunks,users}}

On requesting POST         axios.post(`/api/files/delete/${fileId}`)

Getting error: 

     this._store = new grid.mongo.GridStore(grid.db, this.id || new grid.mongo.ObjectID(), this.name, this.mode, options);
[0]                 ^
[0] 
[0] TypeError: grid.mongo.GridStore is not a constructor
[0]     at new GridReadStream (/home/lenovo/Desktop/react/cstore/node_modules/gridfs-stream/lib/readstream.js:68:17)

This is server.js

      app.get('/image/:filename', (req, res) => {
    gfs.files.findOne({ 
      _id: mongoose.Types.ObjectId(req.params.filename)
      // filename: req.params.filename.toString()
    }, (err, file) => {
      // Check if file
      if (!file || file.length === 0) {
        console.log("not found")
        return res.status(404).json({
          
          err: 'No file exists'
        });
      }

      // Check if image
      if (file.contentType === 'image/jpeg' || file.contentType === 'image/png') {
        // Read output to browser
        console.log(file)
        let id=file._id;

        const readStream = gfs.createReadStream(
          {
            _id: mongoose.Types.ObjectId(req.params.filename)
          }
          // {
          // _id: id
          // }
        )
        readStream.on('error', err => {
            // report stream error
            console.log(err);
        });
        // the response will be the file itself.
        readStream.pipe(res);

      //   let readstream = gfs.createReadStream(mongoose.Types.ObjectId(file._id))
      //   readstream.pipe(res)
      // } else {
        res.status(404).json({
          err: 'Not an image'
        });
      }
    });
  });



  

    mongoose.Promise = global.Promise;
      mongoose.connect(
        mongoURI,
        {
          useNewUrlParser: true,
          useUnifiedTopology: true,
        },
        (err) => {
          if (err) throw err;
          console.log('MongoDB connection established');
        }
      )
      const connection = mongoose.connection;
    
      ///  HANDLING FILE
      let gfs;
      connection.once('open', () => {
        // Init stream
        gfs = Grid(connection.db, mongoose.mongo);
        gfs.collection('uploads');
      });
    
      const storage = new GridFsStorage({
        url: mongoURI, 
        file: (req, file) => {
          return new Promise((resolve, reject) => {
            crypto.randomBytes(16, (err, buf) => {
              if (err) {
                return reject(err);
              }
              const filename = file.originalname;
              const fileInfo = {
                filename: filename,
                bucketName: 'uploads'
              };
              resolve(fileInfo);
            });
          });
        }
      })
    
      const upload = multer({ storage });

Initial:
  const express = require('express');
  const mongoose = require('mongoose');
  const cookieParser = require('cookie-parser');
  const path = require('path');

  const multer = require('multer');
  const {GridFsStorage} = require('multer-gridfs-storage');
  const Grid = require('gridfs-stream');
  const methodOverride = require('method-override')
  const crypto = require('crypto')

  const app = express();

  app.use(express.json());
  app.use(express.urlencoded({ extended: true }));
  app.use(methodOverride('_method'));
  app.use(cookieParser());

  const dotenv=require('dotenv');
  dotenv.config({path:__dirname+'/.env'});

  const mongoURI = process.env.MONGODB_CONNECTION_STRING
node.js mongodb mongoose gridfs multer-gridfs-storage
5个回答
5
投票

GridStore 已弃用。您可以使用GridFSBucket实例对存储桶中的文件调用读写操作。 文档

 let gfs, gridfsBucket;
  conn.once('open', () => {
   gridfsBucket = new mongoose.mongo.GridFSBucket(conn.db, {
   bucketName: 'your_bucket_name'
 });

   gfs = Grid(conn.db, mongoose.mongo);
   gfs.collection('your_bucket_name');
})

if(file.contentType === 'image/jpeg' || file.contentType 
 ==='image/png') 
 {
    const readStream = gridfsBucket.openDownloadStream(file._id);
    readStream.pipe(res);
 }

3
投票

我也遇到过类似的问题。我的解决方案是使用猫鼬版本。该问题在 6.0.5 版本中出现,但在 5.13.7 版本中正常工作


1
投票

GridStore 在 mongoose 版本 6+ 中已弃用。

一种解决方案是弃用 mongoose 版本以使用 5+

其他解决方案是使用GridFsBucked

import grid from 'gridfs-stream';
import mongoose from 'mongoose';

let gfs, gridfsBucket; // declare one more variable with name gridfsBucket
const conn = mongoose.connection;
conn.once('open', () => {
    // Add this line in the code
    gridfsBucket = new mongoose.mongo.GridFSBucket(conn.db, {
        bucketName: 'bucket_name'
    });
    gfs = grid(conn.db, mongoose.mongo);
    gfs.collection('bucket_name');
});

export const getImage = async (request, response) => {
    try {   
        const file = await gfs.files.findOne({ filename: request.params.filename });
        // Till version 5+ we were using this 
        // const readStream = gfs.createReadStream(file.filename);
        // readStream.pipe(response);
        // For version 6+, Replace these two lines with the lines below
        const readStream = gridfsBucket.openDownloadStream(file._id);
        readStream.pipe(response);
    } catch (error) {
        
    }
}

0
投票

您需要使用

GridFs bucket
。这是我在互联网上找到的一个很好的教程,它演示了如何从 mongodb 存储桶上传和下载图像。 https://www.freecodecamp.org/news/gridfs-making-file-uploading-to-mongodb/


0
投票

您可以使用 GridFsBucket 代替。

const mongoose = require("mongoose")
const Grid = require("gridfs-stream")

let gfs, gridfsBucket

const conn = mongoose.connection

conn.once('open', () => {
    gridfsBucket = new mongoose.mongo.GridFSBucket(conn.db, {
        bucketName: "photos"
    })
    gfs = Grid(conn.db, mongoose.mongo)
    gfs.collection('photos')
})

const render_file = async (req, res) => {
    try {    
        const file = gfs.files.findOne({ filename: filename})
        if (!await file) {
            return res.status(500).send({
                message: "No file found!",
            })
        }

        if (await file.contentType == 'image/jpeg' || await file.contentType == 'image/png') {
            var readStream = gridfsBucket.openDownloadStreamByName(filename)
            readStream.pipe(res)
        } else {
            res.status(404).json({
                err: 'File is not an image'
            })
        }

    } catch (err) {     
        return res.status(500).send({
            message: err.message,
        })
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.