将文档放入集合并使用 multer-gridfs-storage 上传文件时,Mongoose save() 不起作用

Mongoose save() does not work when putting documents in collection and uploading files using multer-gridfs-storage

我正在尝试构建一个音乐应用程序,并且在该应用程序的后端工作时(使用 express),我遇到了文档未保存在 mongo 集合中的奇怪问题。

我制作了一个post路由,用户将表单数据提交到该路由,其中​​包含歌曲的mp3文件和歌曲名称(稍后会有更多数据)。

我正在使用 multer 来解析多部分表单数据。 我可以使用 multer-gridfs-storage 将 mp3 文件保存到 mongoDB。我想将名称、艺术家等歌曲信息保存在不同的集合中,这是集合的架构:

import mongoose from 'mongoose';

const Schema = mongoose.Schema;

const SongsInfo = new Schema({
   name: {
     type: String,
     required: true,
   },
});

const Song = mongoose.model('Song', SongsInfo);
export default Song;

index.js 文件:

import Grid from 'gridfs-stream';
import GridFsStorage from 'multer-gridfs-storage';

const app = express();
const conn = mongoose.createConnection(mongoURI);

let gfs;

conn.once('open', () => {
  console.log('Connected to mongodb');
  gfs = Grid(conn.db, mongoose.mongo);
  gfs.collection('songFiles');
});

// storage engine
const storage = new GridFsStorage({
  url: mongoURI,
  file: (req, file) => new Promise((resolve, reject) => {
    crypto.randomBytes(16, (err, buf) => {
      if (err) {
        return reject(err);
      }
      const filename = buf.toString('hex') + 
             path.extname(file.originalname);
      let fileInfo;

    fileInfo = {
      filename,
      bucketName: 'songFiles',
    };

      resolve(fileInfo);
    });
  }),
});
let upload;

middleWare(app);

app.post('/api/uploadSong', async (req, res) => {
  upload = multer({ storage }).any();

  upload(req, res, async (err) => {
    console.log('in');
    if (err) {
      // console.log(err);
      return res.end('Error uploading file.');
    }
    const { name } = req.body;
    // push a Song into songs collection
    const songInfo = new Song({
      name,
    });
    const si = await songInfo.save();    // (*)
    console.log(songInfo);
    res.json({
      songInfo: si,
      file: req.file,
    });
  });
});

在线 (*) 服务器只是冻结,直到请求超时。 控制台上没有显示错误。不知道该怎么办:(

我终于解决了这个问题! 所以我所做的是将模型放入 index.js 文件中,并在这里和那里更改了一些东西..

index.js

const app = express();
mongoose.connect(mongoURI); //(*)
const conn = mongoose.connection; // (*)

let gfs;

conn.once('open', () => {
  console.log('Connected to mongodb');
  gfs = Grid(conn.db, mongoose.mongo);
  gfs.collection('songFiles');
});

// models
const Schema = mongoose.Schema; //(***)

const SongsInfo = new Schema({
  name: {
    type: String,
    required: true,
  },
});

const Song = mongoose.model('Song', SongsInfo);

// storage engine
const storage = new GridFsStorage({
  url: mongoURI,
  file: (req, file) => new Promise((resolve, reject) => {
    crypto.randomBytes(16, (err, buf) => {
      if (err) {
        return reject(err);
      }
      const filename = buf.toString('hex') + path.extname(file.originalname);
      let fileInfo;
      if (file.mimetype === 'image/jpeg' || file.mimetype === 'image/png') {
        fileInfo = {
          filename,
          bucketName: 'imageFiles',
        };
      } else {
        fileInfo = {
          filename,
          bucketName: 'songFiles',
        };
      }
      resolve(fileInfo);
    });
  }),
});
let upload;

middleWare(app);

app.post('/api/uploadSong', async (req, res) => {
  upload = multer({ storage }).any();

  upload(req, res, async (err) => {
    console.log('in');
    if (err) {
      return res.end('Error uploading file.');
    }
    const { name } = req.body;
    // push a Song into songs collection
    const songInfo = new Song({
      name,
    });
    songInfo.save((er, song) => {
      if (!er) {
        res.send('err');
      } else {
        console.log(err, song);
        res.send('err');
      }
    });
  });
});

在第 (***) 行,我使用了相同的已初始化 mongoose 实例。在之前的文件中,我再次从包中导入了它...

起亚!

对于三年来在这里跌跌撞撞的人。我也遇到了这个问题。 Abhishek Mehandiratta 在他们的代码片段中隐藏了答案。

修复
我从实例化猫鼬开始:

connect(connStr)

要做的事:

const conn = createConnection(connStr)

这是重大更改。因此,为了轻松修复,请将您的代码改回使用 connect(...)
我也按照文档和 Youtube 教程以这种方式更改我的代码。对于没有遇到需要了解差异的开发人员来说,这是一种不幸的误导。

我把它改回来了,现在它又能用了(即使是 'multer-gridfs-storage')。您可以通过以下方式引用连接:

import {connection} from "mongoose";
connection.once('open', ...)

为什么会这样?
BenSower writes up the differences between connect and createConnection here。因此,根据我对 BenSower 文章的基本理解,您在创建 'Song' 架构时引用了错误的连接池,因此在保存时引用了错误的连接池。我想这会导致超时,没有进一步查看,但我确定某处存在更多 in-depth 答案。

import mongoose from 'mongoose';
const Song = mongoose.model('Song', SongsInfo);

正如 BenSower 在他们的回答中所说 “对我来说,在同一模块中创建多个连接的最大缺点是您无法通过 mongoose.model,如果它们是在“不同的连接”中定义的。他们对这个很满意。终于克服了这个障碍,我将看看另一个项目上的 createConnection。现在,好的 ol' connect() 会解决这个问题,并且做得很好 :D