使用 mongoose 将带有 graphql 的文件上传到 mongodb

Posted

技术标签:

【中文标题】使用 mongoose 将带有 graphql 的文件上传到 mongodb【英文标题】:Uploading files with graphql to mongodb with mongoose 【发布时间】:2020-12-04 18:38:47 【问题描述】:

我想使用 graphql 解析器将文件上传到 mongodb。 在 server.js 中,我有这个帮助功能来存储文件,该文件被导出以在我的解析器中使用。 该函数基于我在此处找到的内容:https://github.com/jaydenseric/graphql-upload/issues/8),但现在 graphql 中的某些内容发生了变化。例如解构文件对象。我不知道应该在路径变量中找到什么以及我应该如何使用这个 createReadStream(从文件中解构的函数)。

const mongoose = require('mongoose');
const Grid = require('gridfs-stream');
const fs = require('fs');

//...

// Connect to Mongo
mongoose
  .connect(process.env.mongoURI, 
    useNewUrlParser: true,
    useCreateIndex: true,
    useUnifiedTopology: true,
    useFindAndModify: false
  ) // Adding new mongo url parser
  .then(() => console.log('MongoDB Connected...'))
  .catch(err => console.log(err));




const storeFile = async (upload) => 
   const  filename, createReadStream, mimetype  = await upload.then(result => result);

   const bucket = new mongoose.mongo.GridFSBucket(mongoose.connection.db,  bucketName: 'files' );

   const uploadStream = bucket.openUploadStream(filename, 
     contentType: mimetype
   );
   createReadStream()
     .pipe(uploadStream)
     .on('error', console.log('error'))
     .on('finish', console.log('finish'));
 

module.exports =  storeFile 
//...

我的解析器(这里是最小版本,因为现在我只想将文件上传到我的数据库中。在我的一次尝试中,它甚至创建了 fs.files 和 fs.chunks 集合,但没有数据):

Mutation: 
    uploadFile: async (_,  file ) => 
      console.log(file);
      const fileId = await storeFile(file);

      return true;
     
    
  

我现在有这个错误:

未处理的拒绝(错误):GraphQL 错误:“侦听器”参数 必须是函数类型。收到未定义

并且在终端中我打印了“错误”(例如在 pipe.on('error', console.log('error') 语句中)

我只能上传小文件(最大 60 kb),所有更大的文件都不要上传,但所有尝试都会显示错误。

【问题讨论】:

只搜索'gridfs apollo upload' 还是没有new Promise(( 吗?将awaitthen 混合? 【参考方案1】:

好的,我设法解决了。

解析器突变:

const  storeFile  = require('../../server');
//...

uploadFile: async (_,  file ) => 
      const fileId = await storeFile(file).then(result => result);

      return true;
// later I will return something more and create some object etc.
    

来自 server.js 的支持函数

 const storeFile = async (upload) => 
    const  filename, createReadStream, mimetype  = await upload.then(result => result);

    const bucket = new mongoose.mongo.GridFSBucket(mongoose.connection.db,  bucketName: 'files' );
    
    const uploadStream = bucket.openUploadStream(filename, 
      contentType: mimetype
    );
    return new Promise((resolve, reject) => 
      createReadStream()
        .pipe(uploadStream)
        .on('error', reject)
        .on('finish', () => 
            resolve(uploadStream.id)
        )
    )
  

  module.exports =  storeFile 

【讨论】:

能否分享一下从mongo检索文件的代码,以便在前端渲染?

以上是关于使用 mongoose 将带有 graphql 的文件上传到 mongodb的主要内容,如果未能解决你的问题,请参考以下文章

如何使用带有 Mongoose 和 ES6 承诺的 Graphql 中的 find 来解析多条记录

从带有子字段的猫鼬模式生成 Graphql 类型

如何使用 graphql 和 mongoose 进行突变

带有猫鼬的 GraphQL

嵌套对象的模式/解析 graphql/mongoose

嵌套的 Mongoose 查询数据未显示在 GraphQL 查询中