Node.js Mongoose一次插入多个相关记录
目前,我有以下方法,每次有效地插入一首歌词:Node.js Mongoose一次插入多个相关记录,node.js,mongodb,mongoose,Node.js,Mongodb,Mongoose,目前,我有以下方法,每次有效地插入一首歌词: SongSchema.statics.addLyric = function(songId, title, content) { const Lyric = mongoose.model('lyric'); return this.findById(songId).then(song => { const lyric = new Lyric({ title, content, song }); song.lyrics.
SongSchema.statics.addLyric = function(songId, title, content) {
const Lyric = mongoose.model('lyric');
return this.findById(songId).then(song => {
const lyric = new Lyric({ title, content, song });
song.lyrics.push(lyric);
return Promise.all([lyric.save(), song.save()]).then(([lyric, song]) => song);
});
};
然而,我想将其更新为如下内容,我在一个数组中同时传递多个歌词
SongSchema.statics.addLyric = function(songId, lyrics) {
...
};
是否可以一次插入所有歌词,然后仍将更新后的歌曲返回到graphql我所知道的最佳方式如下:
lyrics = lyrics.map((lyric. i) => {lyric, songId: songI[i]});
SongSchema.collection.insertMany(lyrics, {'ordered': false},
(err, data) => {
/*Do your stuff*/
});
songs: [{ type: Schema.Types.ObjectId, ref: 'Lyric' }]
如果存在任何重复的唯一值,Ordered true将抛出错误,如果Ordered true为stop,则仍将抛出错误,但对于非重复的值,将继续插入。
您不需要创建新的架构,但这样也将跳过Momgoose验证。Fair point。与其这样做,不如改为使用,还可以内联创建并“链接”承诺:
SongSchema.statics.addLyrics = function(songId, lyrics) {
const Lyric = mongoose.model('lyric');
return Lyric.insertMany(lyrics).then( lyrics =>
this.findByIdAndUpdate(
songId,
{ "$push": { "lyrics": { "$each": lyrics } } },
{ "new": true }
);
};
它用作接受和数组的修饰符,并执行“原子”操作来更新文档。它比获取文档“然后”在更新之前对其进行修改更高效、更安全
当然,你的歌词的“数组”也不是“很多”,而是作为一个单曲
另一种方法是基于Array.map()
和save()
并行创建实例
SongSchema.statics.addLyrics = function(songId, lyrics) {
const Lyric = mongoose.model('lyric');
lyrics = lyrics.map(lyric => new Lyric(lyric));
return Promise.all([
this.findByIdAndUpdate(
songId,
{ "$push": { "lyrics": { "$each": lyrics } } },
{ "new": true }
),
...lyrics.map(lyric => lyric.save())
]).then(([song, ...lyrics]) => song);
};
但是第一种方法的开销确实较少,而且在解决“所有”承诺之前,Promise.all()
不会响应。所以,如果不进行串联操作,你真的什么都得不到
当然,另一种情况是,您不需要在歌曲
中保留相关ObjectId
值的“数组”,而只需在歌词
条目中记录songId
因此,模式将变成如下所示:
const lyricSchema = new Schema({
title: String,
content: String,
songId: { type: Schema.Types.ObjectId, ref: 'Song' }
})
那么插入就很简单了
lyricSchema.statics.addLyrics = function(songId, lyrics) {
return this.insertMany(lyrics.map(lyric => ({ ...lyric, songId })))
}
在Song
模式中,不保留这样的数组:
lyrics = lyrics.map((lyric. i) => {lyric, songId: songI[i]});
SongSchema.collection.insertMany(lyrics, {'ordered': false},
(err, data) => {
/*Do your stuff*/
});
songs: [{ type: Schema.Types.ObjectId, ref: 'Lyric' }]
将其拆下并更换为
这意味着根本不需要触摸Song
模型,因为您可以简单地插入相关数据,而无需更新数组
不管怎样,现代MongoDB版本确实应该用来“查询”这些信息,并且在父级中维护“数组”有点“反模式”,这通常应该避免
因此,“虚拟”是“可选的”,只是为了方便起见启用populate()
。提供的答案中是否有您认为无法解决问题的内容?如果是,请对答案进行评论,以澄清哪些问题需要解决,哪些问题尚未解决。如果它确实回答了您提出的问题,那么请注意您提出的问题