使用 mongoose、gridfs-stream 和 multer 上传文件时出现 MongoError

2023-11-30

我正在使用 Express 4 运行multer, gridfs 流 and mongoose使用 mongodb,我正在尝试上传文件并将其流式传输到 gridfs。

执行此操作的快速路线定义为:

app.post('/uploadfile', function (req, res) {
    console.dir(req.files);

    // The mongodb instance created when the mongoose.connection is opened
    var db = mongoose.connection.db;

    // The native mongo driver which is used by mongoose
    var mongoDriver = mongoose.mongo;

    // Create a gridfs-stream
    var gfs = new Gridfs(db, mongoDriver);

    var file = req.files.myFile;

    var fileId = new ObjectId();

    console.log("Creating WriteStream");
    var writeStream = gfs.createWriteStream({
        _id: fileId,
        filename: file.originalname,
        mode: 'w',
        content_type: file.mimetype,
        metadata: {
            id: '123',
            number: '2',
            name: "Kenny Erasmuson"
        }
     });
     console.log("Created WriteStream");
     req.pipe(writeStream);
     console.log("Finished!");
});

Express 应用程序运行后,将选择并上传一个文件(通过 HTML multipart/form-data 表单),节点服务器的输出为:

$ node server.js 
Listening on port 8001
{ myFile: 
    { fieldname: 'myFile',
    originalname: 'kenny-credit-rating.pdf',
    name: '1082e5071ede1002c4ae5be6123226d8.pdf',
    encoding: '7bit',
    mimetype: 'application/pdf',
    path: 'uploads/1082e5071ede1002c4ae5be6123226d8.pdf',
    extension: 'pdf',
    size: 110782,
    truncated: false,
    buffer: null } 
}
Creating WriteStream
Created WriteStream
Finished!
/Users/kenny/Dropbox/Dev/fileUploader/node_modules/mongoose/node_modules/mongodb/lib/mongodb/co nnection/base.js:246
    throw message;      
          ^
MongoError: The dollar ($) prefixed field '$conditionalHandlers' in '_id.$conditionalHandlers' is not valid for storage.
at Object.toError (/Users/kenny/Dropbox/Dev/fileUploader/node_modules/mongoose/node_modules/mongodb/lib/mongodb/utils.js:114:11)
at /Users/kenny/Dropbox/Dev/fileUploader/node_modules/mongoose/node_modules/mongodb/lib/mongodb/collection/core.js:569:27
at /Users/kenny/Dropbox/Dev/fileUploader/node_modules/mongoose/node_modules/mongodb/lib/mongodb/db.js:1157:7
at /Users/kenny/Dropbox/Dev/fileUploader/node_modules/mongoose/node_modules/mongodb/lib/mongodb/db.js:1890:9
at Server.Base._callHandler (/Users/kenny/Dropbox/Dev/fileUploader/node_modules/mongoose/node_modules/mongodb/lib/mongodb/connection/base.js:448:41)
at /Users/kenny/Dropbox/Dev/fileUploader/node_modules/mongoose/node_modules/mongodb/lib/mongodb/connection/server.js:481:18
at MongoReply.parseBody (/Users/kenny/Dropbox/Dev/fileUploader/node_modules/mongoose/node_modules/mongodb/lib/mongodb/responses/mongo_reply.js:68:5)
at null.<anonymous> (/Users/kenny/Dropbox/Dev/fileUploader/node_modules/mongoose/node_modules/mongodb/lib/mongodb/connection/server.js:439:20)
at emit (events.js:95:17)
at null.<anonymous> (/Users/kenny/Dropbox/Dev/fileUploader/node_modules/mongoose/node_modules/mongodb/lib/mongodb/connection/connection_pool.js:201:13)

有谁知道导致错误的原因以及如何修复?


问题在于您不只是将文件请求传送到 gridfs-stream。使用 Multer 作为中间件并捕获任何multipart/form-data发布请求。当数据流进入时,Multer(基于Busboy) 监视on('field') and on('file')事件并进行相应的解析。您通过管道传送给 Multer 的不仅仅是一个文件。

这段代码工作正常,因为 Multer 确实已经为你解析出来了req.files and req.body至此:

   // Create a gridfs-stream
   var gfs = new Gridfs(db, mongoDriver);

   var file = req.files.myFile;

   var fileId = new ObjectId();

   console.log("Creating WriteStream");
   var writeStream = gfs.createWriteStream({
        _id: fileId,
        filename: file.originalname,
        mode: 'w',
        content_type: file.mimetype,
        metadata: {
            id: '123',
            number: '2',
            name: "Kenny Erasmuson"
        }
     });
     console.log("Created WriteStream");

但是由于上述原因,您的代码遇到问题的地方在这里:

 req.pipe(writeStream);

我还没有找到一种方法来传输多部分/表单数据发布请求,而不仅仅是直接将文件上传到 GridFS。如果您的 post 请求不包含文件以外的任何内容(意味着表单中没有其他 html 输入字段),那么您可能需要考虑至少针对此路由从中间件中删除 Multer。

对于我的用例,我需要能够接收带有文本输入的 html 表单帖子以及文件上传(我存储有关上传文件的元数据)。以下是我如何使用 Multer 完成我所需要的工作:

var uploadImg = function(req,res) {
      var writestream = gfs.createWriteStream({
        filename: req.files.file.name,
        mode:'w',
        content_type:req.files.file.mimetype,
        metadata:req.body,
      });
    fs.createReadStream(req.files.file.path).pipe(writestream);

    writestream.on('close', function (file) {
        res.send("Success!");
        fs.unlink(req.files.file.path, function (err) {
          if (err) console.error("Error: " + err);
          console.log('successfully deleted : '+ req.files.file.path );
        });
    });

};

默认情况下,Multer 会将您的文件存储在磁盘上。一种快速解决方案是创建一个读取流并将其直接流回 GridFS。写入完成后,删除tmp文件。

附带说明一下,似乎有人认为最好仅在需要它的路由上使用 Multer 作为中间件。您可以在最后一节中阅读有关该想法的更多信息this.

Update

我想我即将找到一种直接流式传输到 GridFS 的方法with元数据通过使用Skipper。我正在查看是否无法获取某些更新船长 gridfs这将获取 html 表单上的文本输入并将其设置为元数据等。对船长-gridfs 的调整似乎很小。当它被冲掉时我会更新。如果您查看船长,请确保您认识到 html 表单输入的顺序(如果有的话)确实很重要。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 mongoose、gridfs-stream 和 multer 上传文件时出现 MongoError 的相关文章

随机推荐

  • 混合模式 C++/CLI 性能注意事项 - 最佳实践

    我有一个 C CLI 库 它调用许多本机 C 方法 我读过许多线程 指出不应混合托管和非托管代码 我找不到任何说明如何避免这些开关以及为什么它会导致性能问题的信息 有人可以分享最佳实践吗 使用 C CLI 的唯一原因是它支持混合托管代码和本
  • 如何每次迭代增加一个字母 N 次并存储在数组中?

    letter array for i A i ZZ i letter i print r letter 从上面的脚本我做了一个循环A B C D ZZ 现在 我想把它变成A C E G I ZZ 2步骤而不是1 我需要指导才能做到这一点 这
  • 在 Firebase 中加入两个节点

    我正在开发一个应用程序 它应该显示来自两个节点 Firebase 的数据 Firebase DB 的结构如下 College 4F2EAB65 id 4F2EAB65 name SomeCollege A3C2ED31 id A3C2ED3
  • pandas:将DataFrame最后一行除以第一行

    这个问题类似于Python Pandas 按第一行划分 DataFrame 我有一个数据框 如下所示 1125400 5430095 1095751 2013 04 02 98 91 NaN 5626 79 2013 04 03 99 29
  • 从 Java 执行 EXE 并从 EXE 获取输入和输出

    我有一个EXE file addOne exe它不断地从控制台上的用户输入一个整数 不是命令行参数 并输出整数 1到控制台上 示例输出如下所示 1 2 6 7 29 30 我正在尝试编写一个java程序 它可以 Run the EXE 不断
  • Swift 2 错误处理问题

    我正在使用 REST 获取 JSON 数据 然后解析它 为此 我使用 NSJSONObjectWithData 据我所知 该方法过去在其参数内有一个错误处理程序 但它不再存在 在我的代码中 let err NSError let optio
  • 自定义 Spring Security 应用程序中的无限循环

    我们尝试用现有的 Spring Security Basic Login 替换开源应用程序中的 REST API 以实现使用令牌的自定义登录 我读过这篇关于该主题的博文 http javattitude com 2014 06 07 spr
  • 将 HTML 实体转换为正确的字符 R

    有谁知道 r 中可以转换的通用函数 228 为其 unicode 字符 我见过一些函数 并将其转换为普通字符 任何帮助 将不胜感激 谢谢 编辑 下面是一条数据记录 我可能有超过100万条记录 除了将数据读入大量向量并针对每个元素更改记录之外
  • 由元组索引的 Python `dict`:获取饼图的一部分

    假设我有 my dict airport London Heathrow airport Tokyo Narita hipsters London Soho 什么是一种有效的 无需扫描所有键 而又优雅的方式来让所有机场脱离这本字典 即预期输
  • 避免 Android 中 EditText 的解析错误

    对于 stackoverflow 社区 我创建了这个方法来将一些 EditText 字段转换为双精度 我添加 if 语句专门是为了避免解析错误 因为我知道我的几个 EditText 字段将留空 然而 它们仍然在运行时不断出现 有人知道避免解
  • Scala 不可变变量和打印

    目前正在学习一个使用 Scala 的课程 我以前从未使用过它 因此语法和本身都是新的 我正在研究一个简单的除法函数 但遇到了一些错误 首先 我使用 var sub m 对吗 在我的代码中 我只是想做 m m n 但你无法更改变量 而且我不确
  • 使用 SAXParser 从 XML 检索 HTML 编码文本

    这是我第一次使用 SAXParser 我在 Android 中使用它 但我认为这对这个特定问题没有影响 并且我正在尝试从 RSS 提要中读取数据 到目前为止 它在很大程度上对我来说工作得很好 但是当它到达包含 HTML 编码文本的标签时 例
  • 如何在django中存储用户数组?

    我有一个 django 模型 它基本上是一个名为Contexts 它包含一些字段 例如name description和一个用户 下面是定义的模型 class Contexts models Model context name model
  • 如何比较三个预训练模型的余弦相似度?

    我有两个语料库 一个包含所有女性领导人的演讲 另一个包含男性领导人的演讲 我想测试这样一个假设 一个语料库中两个单词之间的余弦相似度与另一个语料库中相同两个单词之间的余弦相似度显着不同 这样的 t 检验 或等效的 合乎逻辑并且可能吗 此外
  • 在 Azure Function 中运行 .exe 可执行文件

    我有可执行文件 abcd exe 它包含 与许多 dll 合并 是否可以为 abcd exe 创建 Azure Function 并在 Azure Cloud Functions 中运行它 abcd exe 应用程序 System Diag
  • 使用 SQLite 开发 AIR 应用程序的最佳实践

    我将开始做几个 Adob e AIR 项目 这些项目将使用SQLite提供的功能AIR 由于这是我第一次尝试这样做 我希望得到一些指导 技巧和开发最佳实践 由于此应用程序将访问本地数据库 因此我想我可以在应用程序启动时打开与数据库的连接 并
  • 如何将数组添加到ArrayList中?

    我有一个 int 3 3 数组 它只包含 0 或 1 个值 如果值为1 我想将ArrayList中该值的坐标添加为int 2 数组 但我不知道为什么它总是添加最后一个1值坐标 有什么问题 public static void main St
  • Laravel 5.1 Eloquent isFillable() 单元测试中的差异

    在单元测试中使用时 Eloquent 会忽略模型的可填充设置吗 在非测试情况下 我得到以下输出 这是正确的 因为模型只允许某些可填充字段 m new Model dd m gt isFillable nonexistent field gt
  • 为什么在访问 Ruby on Rails 应用程序中的用户页面时不断收到路由错误?

    我正在尝试向以下位置的微帖子添加评论https github com railstutorial sample app 2nd ed来自迈克尔 哈特尔 Railstutorial 看来如果用户没有发微博 就没有问题 我可以访问他们的页面 但
  • 使用 mongoose、gridfs-stream 和 multer 上传文件时出现 MongoError

    我正在使用 Express 4 运行multer gridfs 流 and mongoose使用 mongodb 我正在尝试上传文件并将其流式传输到 gridfs 执行此操作的快速路线定义为 app post uploadfile func