目前我有以下内容,每次有效插入一首歌词:
ev.dataTransfer.files
但是我想将此更新为以下内容,我在一个数组中一次传递多个歌词...
function dropHandler(ev) {
isDragged = true;
ev.preventDefault();
formData = new FormData($("#form"));
if (ev.dataTransfer.items) {
// Use DataTransferItemList interface to access the file(s)
for (var i = 0; i < ev.dataTransfer.items.length; i++) {
// If dropped items aren't files, reject them
if (ev.dataTransfer.items[i].kind === 'file') {
var file = ev.dataTransfer.items[i].getAsFile();
formData.append("File.PayLoad" + i, file);
}
}
} else {
// Use DataTransfer interface to access the file(s)
for (var i = 0; i < ev.dataTransfer.files.length; i++) {
file = ev.dataTransfer.files[i];
formData.append("File.PayLoad" + i, file);
}
}
}
是否可以一次插入所有歌词并仍然将更新的歌曲返回到graphql
答案 0 :(得分:1)
公平点。而不是findById()
那么它可能更好地使用findByIdAndUpdate()
,而且还可以创建内联和&#34;链&#34;而承诺:
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 }
);
};
使用$each
作为$push
的修饰符,它接受和数组并执行&#34; atomic&#34;更新文档的操作。它比获取文档更有效,更安全。然后&#34;在更新之前修改它。
当然insertMany()
你的阵列也是{#3}}。 lyrics
作为单一写作而不是&#34;许多&#34;。
另一种方法是根据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()
不会响应直到&#34;所有&#34;无论如何,承诺得到了解决。因此,如果不进行系列操作,你真的无法获得任何收益。
另一种情况当然是代替保持&#34;数组&#34;在ObjectId
中相关的Song
值,您只需在songId
条目中记录Lyric
。
因此,架构将变为:
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
架构中,不是像这样保留数组:
songs: [{ type: Schema.Types.ObjectId, ref: 'Lyric' }]
删除它并替换为virtual,
SongSchema.virtual.('songs', {
ref: 'Lyric',
localField: '_id',
foreignField: 'songId'
});
这意味着根本不需要触摸Song
模型,因为您只需插入相关数据而无需更新数组。
现代MongoDB版本确实应该使用$lookup
来&#34;查询&#34;无论如何这个信息,以及&#34;阵列的维护&#34;在父母中是一种反模式&#34;通常应该避免。
&#34;虚拟&#34;因此&#34;是可选的&#34;,只是为了方便而启用populate()
的方法。
答案 1 :(得分:0)
我所知道的最好的方式是这样的:
lyrics = lyrics.map((lyric. i) => {lyric, songId: songI[i]});
SongSchema.collection.insertMany(lyrics, {'ordered': false},
(err, data) => {
/*Do your stuff*/
});
如果有任何重复的唯一值,则序列为true将抛出错误并停止,如果为false,则仍会抛出错误,但插入将继续执行非重复的值。 您不需要创建新的Schema,但这样也会跳过Momgoose验证。