[backend/core] Skip database queries for 0 member collections

This commit is contained in:
Laura Hausmann 2024-03-26 20:07:30 +01:00
parent 715f47cafc
commit 02b80a1a2a
No known key found for this signature in database
GPG key ID: D044E84C5BE01605
4 changed files with 32 additions and 14 deletions

View file

@ -119,8 +119,9 @@ public class NoteRenderer(
return res; return res;
} }
private async Task<List<MentionEntity>> GetMentions(IEnumerable<Note> notes) private async Task<List<MentionEntity>> GetMentions(List<Note> notes)
{ {
if (notes.Count == 0) return [];
var ids = notes.SelectMany(n => n.Mentions).Distinct(); var ids = notes.SelectMany(n => n.Mentions).Distinct();
return await db.Users.IncludeCommonProperties() return await db.Users.IncludeCommonProperties()
.Where(p => ids.Contains(p.Id)) .Where(p => ids.Contains(p.Id))
@ -128,8 +129,9 @@ public class NoteRenderer(
.ToListAsync(); .ToListAsync();
} }
private async Task<List<AttachmentEntity>> GetAttachments(IEnumerable<Note> notes) private async Task<List<AttachmentEntity>> GetAttachments(List<Note> notes)
{ {
if (notes.Count == 0) return [];
var ids = notes.SelectMany(n => n.FileIds).Distinct(); var ids = notes.SelectMany(n => n.FileIds).Distinct();
return await db.DriveFiles.Where(p => ids.Contains(p.Id)) return await db.DriveFiles.Where(p => ids.Contains(p.Id))
.Select(f => new AttachmentEntity .Select(f => new AttachmentEntity
@ -146,14 +148,16 @@ public class NoteRenderer(
.ToListAsync(); .ToListAsync();
} }
internal async Task<List<AccountEntity>> GetAccounts(IEnumerable<User> users) internal async Task<List<AccountEntity>> GetAccounts(List<User> users)
{ {
if (users.Count == 0) return [];
return (await userRenderer.RenderManyAsync(users.DistinctBy(p => p.Id))).ToList(); return (await userRenderer.RenderManyAsync(users.DistinctBy(p => p.Id))).ToList();
} }
private async Task<List<string>> GetLikedNotes(IEnumerable<Note> notes, User? user) private async Task<List<string>> GetLikedNotes(List<Note> notes, User? user)
{ {
if (user == null) return []; if (user == null) return [];
if (notes.Count == 0) return [];
return await db.NoteLikes.Where(p => p.User == user && notes.Contains(p.Note)) return await db.NoteLikes.Where(p => p.User == user && notes.Contains(p.Note))
.Select(p => p.NoteId) .Select(p => p.NoteId)
.ToListAsync(); .ToListAsync();
@ -162,6 +166,7 @@ public class NoteRenderer(
private async Task<List<ReactionEntity>> GetReactions(List<Note> notes, User? user) private async Task<List<ReactionEntity>> GetReactions(List<Note> notes, User? user)
{ {
if (user == null) return []; if (user == null) return [];
if (notes.Count == 0) return [];
var counts = notes.ToDictionary(p => p.Id, p => p.Reactions); var counts = notes.ToDictionary(p => p.Id, p => p.Reactions);
var res = await db.NoteReactions var res = await db.NoteReactions
.Where(p => notes.Contains(p.Note)) .Where(p => notes.Contains(p.Note))
@ -190,26 +195,29 @@ public class NoteRenderer(
return res; return res;
} }
private async Task<List<string>> GetBookmarkedNotes(IEnumerable<Note> notes, User? user) private async Task<List<string>> GetBookmarkedNotes(List<Note> notes, User? user)
{ {
if (user == null) return []; if (user == null) return [];
if (notes.Count == 0) return [];
return await db.NoteBookmarks.Where(p => p.User == user && notes.Contains(p.Note)) return await db.NoteBookmarks.Where(p => p.User == user && notes.Contains(p.Note))
.Select(p => p.NoteId) .Select(p => p.NoteId)
.ToListAsync(); .ToListAsync();
} }
private async Task<List<string>> GetPinnedNotes(IEnumerable<Note> notes, User? user) private async Task<List<string>> GetPinnedNotes(List<Note> notes, User? user)
{ {
if (user == null) return []; if (user == null) return [];
if (notes.Count == 0) return [];
return await db.UserNotePins.Where(p => p.User == user && notes.Contains(p.Note)) return await db.UserNotePins.Where(p => p.User == user && notes.Contains(p.Note))
.Select(p => p.NoteId) .Select(p => p.NoteId)
.ToListAsync(); .ToListAsync();
} }
private async Task<List<string>> GetRenotes(IEnumerable<Note> notes, User? user) private async Task<List<string>> GetRenotes(List<Note> notes, User? user)
{ {
if (user == null) return []; if (user == null) return [];
return await db.Notes.Where(p => p.User == user && p.IsPureRenote && notes.Contains(p.Renote)) if (notes.Count == 0) return [];
return await db.Notes.Where(p => p.User == user && p.IsPureRenote && notes.Contains(p.Renote!))
.Select(p => p.RenoteId) .Select(p => p.RenoteId)
.Where(p => p != null) .Where(p => p != null)
.Distinct() .Distinct()
@ -217,8 +225,9 @@ public class NoteRenderer(
.ToListAsync(); .ToListAsync();
} }
private async Task<List<PollEntity>> GetPolls(IEnumerable<Note> notes, User? user) private async Task<List<PollEntity>> GetPolls(List<Note> notes, User? user)
{ {
if (notes.Count == 0) return [];
var polls = await db.Polls.Where(p => notes.Contains(p.Note)) var polls = await db.Polls.Where(p => notes.Contains(p.Note))
.ToListAsync(); .ToListAsync();
@ -253,9 +262,11 @@ public class NoteRenderer(
.DistinctBy(p => p.Id) .DistinctBy(p => p.Id)
.ToList(); .ToList();
if (noteList.Count == 0) return [];
var data = new NoteRendererDto var data = new NoteRendererDto
{ {
Accounts = accounts ?? await GetAccounts(noteList.Select(p => p.User)), Accounts = accounts ?? await GetAccounts(noteList.Select(p => p.User).ToList()),
Mentions = await GetMentions(noteList), Mentions = await GetMentions(noteList),
Attachments = await GetAttachments(noteList), Attachments = await GetAttachments(noteList),
Polls = await GetPolls(noteList, user), Polls = await GetPolls(noteList, user),

View file

@ -41,6 +41,7 @@ public class NotificationRenderer(NoteRenderer noteRenderer, UserRenderer userRe
) )
{ {
var notificationList = notifications.ToList(); var notificationList = notifications.ToList();
if (notificationList.Count == 0) return [];
var accounts = await noteRenderer.GetAccounts(notificationList.Where(p => p.Notifier != null) var accounts = await noteRenderer.GetAccounts(notificationList.Where(p => p.Notifier != null)
.Select(p => p.Notifier) .Select(p => p.Notifier)
@ -49,7 +50,8 @@ public class NotificationRenderer(NoteRenderer noteRenderer, UserRenderer userRe
.Select(p => p.Note?.Renote?.User) .Select(p => p.Note?.Renote?.User)
.Where(p => p != null)) .Where(p => p != null))
.Cast<User>() .Cast<User>()
.DistinctBy(p => p.Id)); .DistinctBy(p => p.Id)
.ToList());
var notes = await noteRenderer.RenderManyAsync(notificationList.Where(p => p.Note != null) var notes = await noteRenderer.RenderManyAsync(notificationList.Where(p => p.Note != null)
.Select(p => p.Note) .Select(p => p.Note)

View file

@ -104,6 +104,7 @@ public class UserRenderer(IOptions<Config.InstanceSection> config, MfmConverter
public async Task<IEnumerable<AccountEntity>> RenderManyAsync(IEnumerable<User> users) public async Task<IEnumerable<AccountEntity>> RenderManyAsync(IEnumerable<User> users)
{ {
var userList = users.ToList(); var userList = users.ToList();
if (userList.Count == 0) return [];
var emoji = await GetEmoji(userList); var emoji = await GetEmoji(userList);
return await userList.Select(p => RenderAsync(p, emoji)).AwaitAllAsync(); return await userList.Select(p => RenderAsync(p, emoji)).AwaitAllAsync();
} }

View file

@ -69,14 +69,16 @@ public class NoteRenderer(UserRenderer userRenderer, DatabaseContext db, EmojiSe
_ => throw new ArgumentOutOfRangeException(nameof(visibility), visibility, null) _ => throw new ArgumentOutOfRangeException(nameof(visibility), visibility, null)
}; };
private async Task<List<UserResponse>> GetUsers(IEnumerable<Note> notesList) private async Task<List<UserResponse>> GetUsers(List<Note> notesList)
{ {
if (notesList.Count == 0) return [];
var users = notesList.Select(p => p.User).DistinctBy(p => p.Id); var users = notesList.Select(p => p.User).DistinctBy(p => p.Id);
return await userRenderer.RenderMany(users).ToListAsync(); return await userRenderer.RenderMany(users).ToListAsync();
} }
private async Task<List<NoteAttachment>> GetAttachments(IEnumerable<Note> notesList) private async Task<List<NoteAttachment>> GetAttachments(List<Note> notesList)
{ {
if (notesList.Count == 0) return [];
var ids = notesList.SelectMany(p => p.FileIds).Distinct(); var ids = notesList.SelectMany(p => p.FileIds).Distinct();
var files = await db.DriveFiles.Where(p => ids.Contains(p.Id)).ToListAsync(); var files = await db.DriveFiles.Where(p => ids.Contains(p.Id)).ToListAsync();
return files.Select(p => new NoteAttachment return files.Select(p => new NoteAttachment
@ -93,6 +95,7 @@ public class NoteRenderer(UserRenderer userRenderer, DatabaseContext db, EmojiSe
private async Task<List<NoteReactionSchema>> GetReactions(List<Note> notes, User? user) private async Task<List<NoteReactionSchema>> GetReactions(List<Note> notes, User? user)
{ {
if (user == null) return []; if (user == null) return [];
if (notes.Count == 0) return [];
var counts = notes.ToDictionary(p => p.Id, p => p.Reactions); var counts = notes.ToDictionary(p => p.Id, p => p.Reactions);
var res = await db.NoteReactions var res = await db.NoteReactions
.Where(p => notes.Contains(p.Note)) .Where(p => notes.Contains(p.Note))
@ -130,6 +133,7 @@ public class NoteRenderer(UserRenderer userRenderer, DatabaseContext db, EmojiSe
public async Task<IEnumerable<NoteResponse>> RenderMany(IEnumerable<Note> notes, User? user) public async Task<IEnumerable<NoteResponse>> RenderMany(IEnumerable<Note> notes, User? user)
{ {
var notesList = notes.ToList(); var notesList = notes.ToList();
if (notesList.Count == 0) return [];
var allNotes = GetAllNotes(notesList); var allNotes = GetAllNotes(notesList);
var data = new NoteRendererDto var data = new NoteRendererDto
{ {