Search code examples
node.jsmongodbmongoosemongoose-schema

How to get files uploaded via multer using mongoose?


I'm using the below function to get the files uploaded by multer in mongodb.The request is returning empty array.

exports.getPhotos = async (req, res) => {

    const photos = await Photo.find()
        .then(photos => {
            res.status(200).json(photos);
        })
        .catch(err => res.status(500).json({message: "Something went wrong"}));
};

and this is the schema of the image. Is there any way to get the files without specifying the schema?


const mongoose = require("mongoose");
const {ObjectId} = mongoose.Schema;

const photoSchema = new mongoose.Schema({
    lenght: {
        type: String,
    },
    chunkSize: {
        type: String,
        required: true
    },
    uploadDate: {
        type: Date,
    },
    filename: {
        type: String,
    },
    md5: {
        type: String,
    },
    contentType: {
        type: String,
    },

});

module.exports = mongoose.model("Photo", photoSchema);

Solution

  • i use gridfs so it could upload larger files too . a piece of sample code below

    //Connecting to mongo 
    const conn = mongoose.createConnection(mongoURI);
    
    //Init gfs 
    let gfs; 
    conn.once('open', ()=>{
        gfs = GridFsStream(conn.db, mongoose.mongo);
        gfs.collection('uploads');
    })
    //Creating Storage engine 
    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 = buf.toString('hex') + path.extname(file.originalname)
                    //bucket name should match the collection name 
                    const fileInfo = {
                        filename:fileName,
                        bucketName:'uploads'
                    }
                    resolve(fileInfo);
                })
            })
        }
    })
    const upload = multer({storage})
    

    now use this upload const in your paths like the one below there are a few methods for upload like array , single and ... depends on number of files you are uploading . the 'uploadedFile' argument is the name of the file input and you should be consider setting it in your frontend.

    app.post('/',upload.single('uploadedFile'),(req, res)=>{
        res.json('file uploaded')
    })
    

    this upload middleware adds a files to your request which you can use to put file names in your database and later fetch it by that uniqe names with a route like the one below .

    app.get('/: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'
                })
            }
                const readStream = gfs.createReadStream(file.filename);
                readStream.pipe(res)
        })
    })