问题
I am creating a single page application using JavaScript(JQuery) and need to store large video files which size exceed 16Mb. I found that need to use GridFS supporting large files. As I am the new one to MongoDB I am not sure how to use GridFS. There are some good tutorials on creating applications using Node.js, MongoDB and Express but cant find any describing how to use GridFS with MongoDB (not mongoose), Express and Node.js. I managed to put up stuff for uploading files in the BSON-document size limit of 16MB. This is what I have:
var express = require('express');
var path = require('path');
var bodyParser = require('body-parser');
var mongo = require('mongodb');
var monk = require('monk');
var Grid = require('gridfs-stream');
var db = monk('localhost:27017/elearning');
var gfs = Grid(db, mongo);
var routes = require('./routes/index');
var users = require('./routes/users');
var courses = require('./routes/courses');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
// Make our db accessible to our router
app.use(function(req,res,next){
req.db = db;
next();
});
app.use('/', routes);
app.use('/users', users);
app.use('/courses', courses);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
module.exports = app;
And, for example, the courses file is as the following:
var express = require('express');
var router = express.Router();
/* GET courses listing */
router.get('/courselist', function(req, res) {
var db = req.db;
var collection = db.get('courselist');
collection.find({},{},function(e,docs){
res.json(docs);
})
});
/* POST courses data */
router.post('/courselist', function(req, res) {
var db = req.db;
var collection = db.get('courselist');
collection.insert(req.body, function(err, result){
res.send(
(err === null) ? { msg: '' } : { msg: err }
);
});
});
/* Delete courses data */
router.delete('/courselist/:id', function(req, res) {
var db = req.db;
var collection = db.get('courselist');
var userToDelete = req.params.id;
collection.remove({ '_id' : userToDelete }, function(err) {
res.send((err === null) ? { msg: '' } : { msg:'error: ' + err });
});
});
module.exports = router;
I would be extremely grateful for your help, if you could tell how should I edit above files in order to utilize GridFS and be able to get, upload and delete video and picture files from my elearning database.
回答1:
You can do direct uploading without using mongoose
using gridfs-stream as simple as:
var express = require('express'),
mongo = require('mongodb'),
Grid = require('gridfs-stream'),
db = new mongo.Db('node-cheat-db', new mongo.Server("localhost", 27017)),
gfs = Grid(db, mongo),
app = express();
db.open(function (err) {
if (err) return handleError(err);
var gfs = Grid(db, mongo);
console.log('All set! Start uploading :)');
});
//POST http://localhost:3000/file
app.post('/file', function (req, res) {
var writeStream = gfs.createWriteStream({
filename: 'file_name_here'
});
writeStream.on('close', function (file) {
res.send(`File has been uploaded ${file._id}`);
});
req.pipe(writeStream);
});
//GET http://localhost:3000/file/[mongo_id_of_file_here]
app.get('/file/:fileId', function (req, res) {
gfs.createReadStream({
_id: req.params.fileId // or provide filename: 'file_name_here'
}).pipe(res);
});
app.listen(process.env.PORT || 3000);
for complete files and running project:
Clone node-cheat direct_upload_gridfs, run node app
followed by npm install express mongodb gridfs-stream
.
OR
Follow baby steps at Node-Cheat Direct Upload via GridFS README.md
回答2:
Very late but I found previous answer outdated. I'm posting this because this might help newbies like me. To run it, please follow previous answers guide. All credit goes to @ZeeshanHassanMemon.
var express = require('express'),
mongoose = require('mongoose'),
Grid = require('gridfs-stream'),
app = express();
Grid.mongo = mongoose.mongo;
conn = mongoose.createConnection('mongodb://localhost/node-cheat-db');
conn.once('open', function () {
var gfs = Grid(conn.db);
app.set('gridfs', gfs);
console.log('all set');
});
//POST http://localhost:3000/file
app.post('/file', function (req, res) {
var gridfs = app.get('gridfs');
var writeStream = gridfs.createWriteStream({
filename: 'file_name_here'
});
writeStream.on('close', function (file) {
res.send(`File has been uploaded ${file._id}`);
});
req.pipe(writeStream);
});
//GET http://localhost:3000/file/[mongo_id_of_file_here]
app.get('/file/:fileId', function (req, res) {
var gridfs = app.get('gridfs');
gridfs.createReadStream({
_id: req.params.fileId // or provide filename: 'file_name_here'
}).pipe(res);
});
app.listen(process.env.PORT || 3000);
来源:https://stackoverflow.com/questions/31252063/using-mongodb-express-node-js-and-gridfs-stream-for-storing-video-and-picture