mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-06-08 00:39:25 +01:00
Add batch method for people names
This commit is contained in:
@@ -3394,6 +3394,12 @@ namespace Emby.Server.Implementations.Library
|
||||
return _peopleRepository.GetPeopleNames(query);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IReadOnlyDictionary<Guid, IReadOnlyList<string>> GetPeopleNamesByItem(IReadOnlyList<Guid> itemIds, IReadOnlyList<string> personTypes)
|
||||
{
|
||||
return _peopleRepository.GetPeopleNamesByItem(itemIds, personTypes);
|
||||
}
|
||||
|
||||
public void UpdatePeople(BaseItem item, List<PersonInfo> people)
|
||||
{
|
||||
UpdatePeopleAsync(item, people, CancellationToken.None).GetAwaiter().GetResult();
|
||||
|
||||
@@ -165,6 +165,64 @@ public class PeopleRepository(IDbContextFactory<JellyfinDbContext> dbProvider, I
|
||||
transaction.Commit();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IReadOnlyDictionary<Guid, IReadOnlyList<string>> GetPeopleNamesByItem(IReadOnlyList<Guid> itemIds, IReadOnlyList<string> personTypes)
|
||||
{
|
||||
if (itemIds.Count == 0)
|
||||
{
|
||||
return new Dictionary<Guid, IReadOnlyList<string>>();
|
||||
}
|
||||
|
||||
using var context = _dbProvider.CreateDbContext();
|
||||
var query = context.PeopleBaseItemMap
|
||||
.AsNoTracking()
|
||||
.Where(m => itemIds.Contains(m.ItemId));
|
||||
|
||||
if (personTypes.Count > 0)
|
||||
{
|
||||
query = query.Where(m => personTypes.Contains(m.People.PersonType));
|
||||
}
|
||||
|
||||
// One round-trip: pull (ItemId, ListOrder, Name) sorted by ItemId+ListOrder, group in memory.
|
||||
var rows = query
|
||||
.OrderBy(m => m.ItemId)
|
||||
.ThenBy(m => m.ListOrder)
|
||||
.Select(m => new { m.ItemId, m.People.Name })
|
||||
.ToArray();
|
||||
|
||||
var result = new Dictionary<Guid, IReadOnlyList<string>>();
|
||||
List<string>? current = null;
|
||||
var currentId = Guid.Empty;
|
||||
var seen = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
foreach (var row in rows)
|
||||
{
|
||||
if (row.ItemId != currentId)
|
||||
{
|
||||
if (current is { Count: > 0 })
|
||||
{
|
||||
result[currentId] = current;
|
||||
}
|
||||
|
||||
currentId = row.ItemId;
|
||||
current = new List<string>();
|
||||
seen.Clear();
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(row.Name) && seen.Add(row.Name))
|
||||
{
|
||||
current!.Add(row.Name);
|
||||
}
|
||||
}
|
||||
|
||||
if (current is { Count: > 0 })
|
||||
{
|
||||
result[currentId] = current;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private PersonInfo Map(People people)
|
||||
{
|
||||
var mapping = people.BaseItems?.FirstOrDefault();
|
||||
|
||||
@@ -597,6 +597,14 @@ namespace MediaBrowser.Controller.Library
|
||||
/// <returns>List<System.String>.</returns>
|
||||
IReadOnlyList<string> GetPeopleNames(InternalPeopleQuery query);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the people names per item for a batch of item IDs in a single DB round-trip.
|
||||
/// </summary>
|
||||
/// <param name="itemIds">The item IDs to look up.</param>
|
||||
/// <param name="personTypes">Optional person types to include. Empty for all.</param>
|
||||
/// <returns>Dictionary keyed by item id; values are the per-item people names. Items with no people are absent.</returns>
|
||||
IReadOnlyDictionary<Guid, IReadOnlyList<string>> GetPeopleNamesByItem(IReadOnlyList<Guid> itemIds, IReadOnlyList<string> personTypes);
|
||||
|
||||
/// <summary>
|
||||
/// Queries the items.
|
||||
/// </summary>
|
||||
|
||||
@@ -32,4 +32,14 @@ public interface IPeopleRepository
|
||||
/// <param name="filter">The query.</param>
|
||||
/// <returns>The list of people names matching the filter.</returns>
|
||||
IReadOnlyList<string> GetPeopleNames(InternalPeopleQuery filter);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the people names per item for a batch of item IDs, preserving per-item list order.
|
||||
/// One database round-trip for the whole batch; grouped by item id in memory.
|
||||
/// Items with no people are omitted from the returned dictionary.
|
||||
/// </summary>
|
||||
/// <param name="itemIds">The item IDs to get people for.</param>
|
||||
/// <param name="personTypes">Optional person types to include (e.g. "Actor", "Director"). Empty for all.</param>
|
||||
/// <returns>Dictionary keyed by item id; values are the per-item people names.</returns>
|
||||
IReadOnlyDictionary<Guid, IReadOnlyList<string>> GetPeopleNamesByItem(IReadOnlyList<Guid> itemIds, IReadOnlyList<string> personTypes);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user