fix(server): DriveFile related N+1 query when call note packMany (#10133)

* fix(server): DriveFile related N+1 query when call note packMany

* Update packages/backend/src/misc/is-not-null.ts

Co-authored-by: Acid Chicken (硫酸鶏) <root@acid-chicken.com>

* ignore lint

* 途中でやめたやつが混入していた

* fix: 順番通りである必要がある場所で順番通りになっていなかった

---------

Co-authored-by: Acid Chicken (硫酸鶏) <root@acid-chicken.com>
This commit is contained in:
rinsuki 2023-03-03 10:06:59 +09:00 committed by GitHub
parent 5248395fc5
commit 452a48e7f4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 66 additions and 58 deletions

View file

@ -11,6 +11,7 @@ import type { Note } from '@/models/entities/Note.js';
import type { NoteReaction } from '@/models/entities/NoteReaction.js';
import type { UsersRepository, NotesRepository, FollowingsRepository, PollsRepository, PollVotesRepository, NoteReactionsRepository, ChannelsRepository, DriveFilesRepository } from '@/models/index.js';
import { bindThis } from '@/decorators.js';
import { isNotNull } from '@/misc/is-not-null.js';
import type { OnModuleInit } from '@nestjs/common';
import type { CustomEmojiService } from '../CustomEmojiService.js';
import type { ReactionService } from '../ReactionService.js';
@ -257,6 +258,7 @@ export class NoteEntityService implements OnModuleInit {
skipHide?: boolean;
_hint_?: {
myReactions: Map<Note['id'], NoteReaction | null>;
packedFiles: Map<Note['fileIds'][number], Packed<'DriveFile'>>;
};
},
): Promise<Packed<'Note'>> {
@ -284,6 +286,7 @@ export class NoteEntityService implements OnModuleInit {
const reactionEmojiNames = Object.keys(note.reactions)
.filter(x => x.startsWith(':') && x.includes('@') && !x.includes('@.')) // リモートカスタム絵文字のみ
.map(x => this.reactionService.decodeReaction(x).reaction.replaceAll(':', ''));
const packedFiles = options?._hint_?.packedFiles;
const packed: Packed<'Note'> = await awaitAll({
id: note.id,
@ -304,7 +307,7 @@ export class NoteEntityService implements OnModuleInit {
emojis: host != null ? this.customEmojiService.populateEmojis(note.emojis, host) : undefined,
tags: note.tags.length > 0 ? note.tags : undefined,
fileIds: note.fileIds,
files: this.driveFileEntityService.packMany(note.fileIds),
files: packedFiles != null ? note.fileIds.map(fi => packedFiles.get(fi)).filter(isNotNull) : this.driveFileEntityService.packManyByIds(note.fileIds),
replyId: note.replyId,
renoteId: note.renoteId,
channelId: note.channelId ?? undefined,
@ -388,11 +391,14 @@ export class NoteEntityService implements OnModuleInit {
}
await this.customEmojiService.prefetchEmojis(this.customEmojiService.aggregateNoteEmojis(notes));
const fileIds = notes.flatMap(n => n.fileIds);
const packedFiles = await this.driveFileEntityService.packManyByIdsMap(fileIds);
return await Promise.all(notes.map(n => this.pack(n, me, {
...options,
_hint_: {
myReactions: myReactionsMap,
packedFiles,
},
})));
}