为什么我不能使用来自相关mongo文档的id在GridFS上设置id

我的应用程序使用节点0.10.1,表示3.1.1,mongoose3.6.4,mongo 2.4.1和gridfs-stream 0.4.0。

我已经build立mongoose和网格stream与共享连接如下:

/************* app.js ***************/ //Added this in edit to show setup of mongoose and gridfs-stream var mongoose = require("mongoose"); var Grid = require('gridfs-stream'); Grid.mongo = mongoose.mongo; global.conn = mongoose.createConnection(dbUri); conn.once('open', function(){ global.gfs = Grid(conn.db); }); 

我正在尝试使用gridfs-stream来上传/下载文件。 我的上传看起来像:

 exports.uploadFile = function(req, res){ var file = req.files.upload; var docId = mongoose.Types.ObjectId(req.query.docId); var filename = req.query.ileName; var contentType = file.type; if(!file) return res.send({result: 'NO_FILE_UPLOADED'}); var writestream = gfs.createWriteStream({ _id: docId, filename: filename, mode: 'w', root: 'documents' }); // more here but ommitted }; 

docId来自mongo文档的ObjectId。

上传似乎工作。 我可以看到使用mongo控制台上传的文件:

 db.documents.files.findOne() { "_id" : ObjectId("5167604d1b63f2541400003d"), "filename" : "borrower1.fnm", "contentType" : "binary/octet-stream", "length" : 3473, "chunkSize" : 262144, "uploadDate" : ISODate("2013-04-12T15:43:06.723Z"), "aliases" : null, "metadata" : null, "md5" : "04c85fe5e9ba0e798fd5eb90f1cb62be" } 

当我尝试下载文件时,使用以下内容:

 exports.downloadFile = function(req, res){ var docId = mongoose.Types.ObjectId(req.query.docId); var readstream = gfs.createReadStream({_id: docId}); readstream.pipe(res); }; 

引发以下错误:

 Error: 5167604d1b63f2541400003d does not exist 

当我试图直接从mongo控制台使用似乎存储在gridfs数据库中的_id检索文件时,它将返回null。 但是,如果我尝试使用文件名检索文件,mongo控制台将检索该文件。

不能使用相关mongo文档的_id来设置gridfs中上传文件的_id? 如果是这样,我的代码是不正确的? 如果没有,有没有办法让网格生成ID并获得分配的ID,所以我可以将其存储在相关的mongo文件?

谢谢你的帮助!

我要回答我自己的问题,因为我在通过mongoose server.js和gridfs-stream的源代码时find了答案。

您可以使用相关文档的ObjectId作为存储文件的ObjectId。

但是,如果您在上传时提供“根”选项,则还需要在下载代码中使用它。 否则,mongoose认为该集合是基础集合。

所以这个工作:

 exports.uploadFile = function(req, res){ var file = req.files.upload; var docId = mongoose.Types.ObjectId(req.query.docId); var filename = req.query.ileName; var contentType = file.type; if(!file) return res.send({result: 'NO_FILE_UPLOADED'}); var writestream = gfs.createWriteStream({ _id: docId, filename: filename, mode: 'w', root: 'documents' }); // more here but ommitted }; exports.downloadFile = function(req, res){ var id = gfs.tryParseObjectId(req.query.docId); //note that options now includes 'root' var options = {_id: id, root: 'documents'}; try{ gfs.createReadStream(options).pipe(res); } catch(err){ console.log(err); } }; 

我看了一下gridfs-stream页面,是不是给它分配了mongoose驱动。

 var conn = mongoose.createConnection(..); conn.once('open', function () { var gfs = Grid(conn.db, mongoose.mongo); //missing parameter // all set! }) 

要么

 Grid.mongo = mongoose.mongo; //missing var conn = mongoose.createConnection(..); conn.once('open', function () { var gfs = Grid(conn.db); // all set! }); 

你有没有尝试将req.query.docId转换为ObjectId? 如果您从查询中接收到值,则它将是string,因此如果在上载过程中使用了此类_id,则需要将其转换为ObjectId。

 exports.downloadFile = function(req, res){ console.log(req.query.docId); var readstream = gfs.createReadStream({_id: mongoose.Types.ObjectId(req.query.docId)}); readstream.pipe(res); };