我正在为纸质音乐杂志建立我的第一个个人项目,为他们的订阅者提供在线阅读。我已经知道我将不得不将大量重复的代码重构为可重用的代码,但我现在只想让事情正常工作。
这些是我用来构建模型/控制器的集合:
- 艺术家
- 相册
- 用户(管理员、作者、订阅者)
- 编年史(专辑短评)
- 文章(专辑长评)
- 采访(大部分时间与文章相关)
- 问题,参考所有编年史、文章和访谈(ObjectID 数组)
Artist简单明了,只有 'name'、'country' 和一个空的 'albums' 数组:
exports.createArtist = catchAsync(async (req, res, next) => {
req.body.createdBy = mongoose.Types.ObjectId(req.user._id)
req.body.albums = []
const newArtist = await Artist.create(req.body)
res.status(201).json({
status: 'success',
data: {
article: newArtist,
},
})
})
专辑有点复杂,但艺术家“姓名”被转换为其 ObjectId 以供参考,并使用新创建的专辑 ObjectId 填充艺术家的“专辑”数组
exports.createAlbum = catchAsync(async (req, res, next) => {
// Add createdBy automatically in the req.body
req.body.createdBy = mongoose.Types.ObjectId(req.user._id)
// Find the album's artist by its name
const relatedArtist = await Artist.findOne({ name: req.body.artist })
if (!relatedArtist) {
return next(new AppError('No artist with that name, please check', 404))
}
// replace the name of the artist with its objectID for auto referencing
req.body.artist = mongoose.Types.ObjectId(relatedArtist._id)
// save album
const newAlbum = await Album.create(req.body)
// add the saved album into the albums' array in the artist collection
relatedArtist.albums.push(mongoose.Types.ObjectId(newAlbum._id))
await relatedArtist.save()
res.status(201).json({
status: 'success',
data: {
album: newAlbum,
},
})
})
Chronicle 有点相似,但在此过程中涉及其他 3 个集合:专辑和艺术家数据的集合,以及填充当前问题的“chronicles”数组:
exports.createChronicle = catchAsync(async (req, res, next) => {
// Add author automatically in the req.body
req.body.author = mongoose.Types.ObjectId(req.user._id)
// Find artist & album of the chronicle in the respective collections
const artist = await Artist.findOne({ name: req.body.artist })
const album = await Album.findOne({ title: req.body.album })
const issue = await Issue.findOne({ issueNumber: req.body.belongsToIssue })
if (!artist) {
return next(new AppError('No artist with that name, please check.', 404))
}
if (!album) {
return next(new AppError('No album with that name, please check.', 404))
}
if (!issue) {
return next(new AppError('No issue with that number, please check.', 404))
}
// replace the name of the artist and album with its objectID for auto referencing
req.body.artist = mongoose.Types.ObjectId(artist._id)
req.body.album = mongoose.Types.ObjectId(album._id)
// Create Chronicle unique slug & add to req.body
req.body.slug = slugify(`${artist.name} ${album.title} ${album.year}`, {
lower: true,
})
// Save new Chronicle
const newChronicle = await Chronicle.create(req.body)
// Push new Chronicle ID into the array of the corresponding Issue
issue.chronicles.push(mongoose.Types.ObjectId(newChronicle._id))
await issue.save()
res.status(201).json({
status: 'success',
data: {
chronicle: newChronicle,
},
})
})
我的问题现在出现在“文章”上:一篇文章可以是关于几张专辑的(所以不仅仅是一个 ObjectId,而是一个 ObjectId 数组!)并且可以由多个作者(1 到 3 之间)签名。每次执行时我都必须遍历两个数组:
await Album.find({title: req.body.title})
await User.find({author: req.body.author})
然后通过其 ObjectId 交换 req.body.albums 和 req.body.authors 中的名称,最后将 req.body.albums + authors 从字符串数组转换为 ObjectIds 数组,尤其是在数组是指针的情况下(我猜我必须使用解构的重复数组)。我知道我无法在map()循环的forEach()中执行异步操作,但还没有弄清楚如何使它工作。我的研究使我认为我必须使用Promise.all()但到目前为止还没有弄清楚如何使用,直到现在我所有的试验和错误都失败了,所以我必须以错误的方式执行此操作或不了解该过程。
感谢您的帮助和技巧!