将文档放入集合并使用 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
我正在尝试构建一个音乐应用程序,并且在该应用程序的后端工作时(使用 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