You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js结合Monk将图片存储至MongoDB的实现方法及示例请求

Absolutely, you can store images in MongoDB using Monk with GridFS—no Mongoose required! Let’s walk through a complete, working example step by step, using Multer for handling file uploads and GridFS for managing binary data storage.


Prerequisites

First, make sure you have these packages installed in your Node.js project:

  • monk: Lightweight MongoDB wrapper
  • multer: Handles multipart/form-data file uploads
  • gridfs-stream: Streams data to/from GridFS
  • mongodb: Native MongoDB driver (required by gridfs-stream)
Step 1: Install Dependencies

Run this command in your project directory:

npm install monk multer gridfs-stream mongodb
Step 2: Initialize Monk & GridFS

Monk doesn’t have built-in GridFS support, so we’ll pull the native MongoDB driver instance from Monk’s connection to set up GridFS:

const monk = require('monk');
const Grid = require('gridfs-stream');
const express = require('express');
const app = express();

// Connect to your MongoDB database
const db = monk('mongodb://localhost:27017/imageStorageDB');
db.then(() => console.log('Connected to MongoDB successfully'));

// Initialize GridFS
let gfs;
db.then((nativeDb) => {
  gfs = Grid(nativeDb, require('mongodb'));
  gfs.collection('imageUploads'); // Name your GridFS collection (can be anything)
});
Step 3: Configure Multer for File Handling

We’ll use Multer’s memory storage to hold uploaded files temporarily before streaming them to GridFS:

const multer = require('multer');

const storage = multer.memoryStorage();
const upload = multer({
  storage: storage,
  limits: { fileSize: 5 * 1024 * 1024 }, // Limit files to 5MB (adjust as needed)
  fileFilter: (req, file, cb) => {
    // Only allow image files
    if (file.mimetype.startsWith('image/')) {
      cb(null, true);
    } else {
      cb(new Error('Only image files are allowed!'), false);
    }
  }
});
Step 4: Create an Upload Endpoint

This Express route will accept an uploaded image, stream it to GridFS, and return the stored file’s details:

// Upload route (expects a file with form field name 'image')
app.post('/upload', upload.single('image'), (req, res) => {
  if (!req.file) {
    return res.status(400).send('No file was uploaded.');
  }

  // Set up GridFS write stream
  const writeStream = gfs.createWriteStream({
    filename: req.file.originalname,
    contentType: req.file.mimetype,
    metadata: {
      originalSize: req.file.size,
      uploadDate: new Date()
    }
  });

  // Stream the uploaded file buffer to GridFS
  writeStream.end(req.file.buffer);

  // Handle stream events
  writeStream.on('close', (storedFile) => {
    res.json({
      message: 'Image stored successfully!',
      fileId: storedFile._id.toString(),
      filename: storedFile.filename,
      contentType: storedFile.contentType
    });
  });

  writeStream.on('error', (err) => {
    res.status(500).send(`Failed to store image: ${err.message}`);
  });
});
Step 5: Create a Download Endpoint

Add routes to retrieve and serve stored images by either filename or MongoDB ObjectID:

// Get image by filename
app.get('/image/:filename', (req, res) => {
  gfs.files.findOne({ filename: req.params.filename }, (err, file) => {
    if (!file || err) {
      return res.status(404).send('Image not found.');
    }

    // Ensure we're serving an image
    if (file.contentType.startsWith('image/')) {
      const readStream = gfs.createReadStream(file.filename);
      readStream.pipe(res);
    } else {
      res.status(400).send('Requested file is not an image.');
    }
  });
});

// Get image by MongoDB ObjectID
app.get('/image/id/:id', (req, res) => {
  // Use monk.id() to convert string ID to MongoDB ObjectID
  gfs.files.findOne({ _id: monk.id(req.params.id) }, (err, file) => {
    if (!file || err) {
      return res.status(404).send('Image not found.');
    }

    if (file.contentType.startsWith('image/')) {
      const readStream = gfs.createReadStream({ _id: req.params.id });
      readStream.pipe(res);
    } else {
      res.status(400).send('Requested file is not an image.');
    }
  });
});

// Start the server
const PORT = 3000;
app.listen(PORT, () => console.log(`Server running on port ${PORT}`));
Key Tips for Production
  • Add proper error handling for MongoDB connection failures and stream errors
  • Consider adding authentication to your upload/download routes
  • For large files, you might want to adjust Multer’s memory limits or use disk storage instead (but ensure you clean up temporary files)
  • You can add a delete endpoint using gfs.remove({ _id: fileId }, (err) => { ... })

内容的提问来源于stack exchange,提问作者Cory Sparks

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:05:53