【问题标题】:Store variable length Array in MongoDB with Mongoose使用 Mongoose 在 MongoDB 中存储可变长度数组
【发布时间】:2018-10-31 21:02:00
【问题描述】:

我在客户端使用了一个表单,用户可以在该表单上上传任意数量的文件,然后我使用 axios 将其全部发送出去。

在 NodeJS 中接收它,我正在使用 Multer 使用 req.files 获取文件及其信息,如下所示:

[ { fieldname: 'file1',
    originalname: 'someimage.jpg',
    encoding: '7bit',
    mimetype: 'image/jpeg',
    destination: './uploads/',
    filename: '71027041755f49366c132555066d5b89',
    path: 'uploads\\71027041755f49366c132555066d5b89',
    size: 69336 } ]

正如我们所见,它是一个数组,可以包含多个文件,这很好,但我的问题来了。

我想使用 Mongoose 将这些文件的信息存储在 MongoDB 中,以便我知道文件的调用方式、目的地、大小等。

我在 Mongoose 中这样定义了一个 Schema:

const someSchema = new Schema({
  files: {
    originalname: String,
    filename: String,
    mimetype: String,
    size: String,
    destination: String,
    path: String
  }
});

但这只会让我存储一个文件信息。我之前也尝试过:

const someSchema = new Schema({
  files: Array
});

但这行不通 (TypeError: Cannot set property 'originalname' of undefined)。我还尝试设置Object,这也会出错(TypeError: Cannot read property '0' of undefined)。

顺便说一句,我正在阅读“文件”:

 for (let i = 0; i < req.files.length; i++) {
      someschema.files[i].originalname = req.files[i].originalname;
      someschema.files[i].filename = req.files[i].filename;
      someschema.files[i].mimetype = req.files[i].mimetype;
      someschema.files[i].size = req.files[i].size;
      someschema.files[i].destination = req.files[i].destination;
      someschema.files[i].path = req.files[i].path;
    }

记录以上每个req.files[i].XXX,一切都按应有的方式定义。

有没有办法制作一个接受多个“文件”的架构?

换句话说:如果可能的话,有没有办法制作一个接受具有多个对象的数组的架构?

提前致谢。

编辑:我想出了files: [Object],但这也行不通(TypeError)。

【问题讨论】:

    标签: node.js mongodb mongoose


    【解决方案1】:

    使用$addToSet 将另一个对象推送到数组中。

    您可以使用$push 代替$addToSet,但这将允许您插入重复的对象。

    架构:

    var UserSchema = new Schema({
      files: [{
        originalname: String,
        filename: String,
        mimetype: String,
        size: String,
        destination: String,
        path: String
      }]
    });
    

    将另一个对象插入到数组中。

    let obj = {
      originalname: "11",
      filename: "11",
      mimetype: "11",
      size: "11",
      destination: "11",
      path: "11"
    }
    
    User.update({
      _id: mongoose.Types.ObjectId("5bd99f95f255307d51f32578")
    }, {
        $addToSet: { files: obj}
    }).exec(function(err, updated){
      console.log(updated);
    })
    

    ======== 更新=======

    您的someschema.files 的长度最短。例如2 并且您的迭代次数超过了i 索引。试试下面:

    for (let i = 0; i < req.files.length; i++) {
      let obj = {};
      obj.originalname = req.files[i].originalname;
      obj.filename = req.files[i].filename;
      obj.mimetype = req.files[i].mimetype;
      obj.size = req.files[i].size;
      obj.destination = req.files[i].destination;
      obj.path = req.files[i].path;
    
      someschema.files.push(obj); // lastly push whole object.
    }
    

    【讨论】:

    • 用req.files[i] 存储它,这个模式也给出了TypeError: Cannot set property 'originalname' of undefined。我相信我的错误是用 [i] 将它写入一个数组,但是应该怎么做呢?
    • 这是因为您的someschema.files 有一些最低长度。例如 2 并且您的迭代次数超过了 index
    • 成功了。非常感谢。也感谢您解释为什么它以前没有工作。
    • @Fusselldieb,我的荣幸。
    【解决方案2】:

    尝试将您的字段包装在 [] 中

    const someSchema = new Schema({
      files: [{
        originalname: String,
        filename: String,
        mimetype: String,
        size: String,
        destination: String,
        path: String
      }]
    });
    

    【讨论】:

    • 感谢您的回答,但这基本上是其他答案也提出的。
    猜你喜欢
    • 1970-01-01
    • 2018-06-27
    • 2015-01-25
    • 2019-05-29
    • 1970-01-01
    • 1970-01-01
    • 2013-10-27
    • 2020-11-20
    相关资源
    最近更新 更多