aboutsummaryrefslogtreecommitdiff
path: root/Emby.Server.Implementations/Library
diff options
context:
space:
mode:
Diffstat (limited to 'Emby.Server.Implementations/Library')
-rw-r--r--Emby.Server.Implementations/Library/SimilarItems/MovieSimilarItemsProvider.cs52
1 files changed, 29 insertions, 23 deletions
diff --git a/Emby.Server.Implementations/Library/SimilarItems/MovieSimilarItemsProvider.cs b/Emby.Server.Implementations/Library/SimilarItems/MovieSimilarItemsProvider.cs
index 29cde6a570..d73120e691 100644
--- a/Emby.Server.Implementations/Library/SimilarItems/MovieSimilarItemsProvider.cs
+++ b/Emby.Server.Implementations/Library/SimilarItems/MovieSimilarItemsProvider.cs
@@ -41,11 +41,14 @@ public sealed class MovieSimilarItemsProvider : ILocalSimilarItemsProvider<Movie
(ItemValueType.Studios, StudioWeight)
];
- private static readonly (string[] PersonTypes, int Weight)[] _peopleDimensions =
- [
- ([nameof(PersonKind.Director)], DirectorWeight),
- ([nameof(PersonKind.Actor), nameof(PersonKind.GuestStar)], ActorWeight)
- ];
+ private static readonly Dictionary<string, int> _personTypeWeights = new(StringComparer.Ordinal)
+ {
+ [nameof(PersonKind.Director)] = DirectorWeight,
+ [nameof(PersonKind.Actor)] = ActorWeight,
+ [nameof(PersonKind.GuestStar)] = ActorWeight,
+ };
+
+ private static readonly string[] _scoredPersonTypes = [.. _personTypeWeights.Keys];
private readonly IDbContextFactory<JellyfinDbContext> _dbProvider;
private readonly IItemQueryHelpers _queryHelpers;
@@ -194,8 +197,7 @@ public sealed class MovieSimilarItemsProvider : ILocalSimilarItemsProvider<Movie
return result;
}
- // Phase 4: One entity load for all results. AsSplitQuery avoids a SQL Cartesian
- // product across the multiple collection Includes added by ApplyNavigations.
+ // Phase 4: One entity load for all results
var allOrderedIdsList = allOrderedIds.ToList();
var entities = await _queryHelpers.ApplyNavigations(
context.BaseItems.AsNoTracking().WhereOneOrMany(allOrderedIdsList, e => e.Id),
@@ -257,27 +259,31 @@ public sealed class MovieSimilarItemsProvider : ILocalSimilarItemsProvider<Movie
ApplyDimensionScores(sourceIds, sourceMap, keyToCandidates, weight, result);
}
- foreach (var (personTypes, weight) in _peopleDimensions)
+ var personSourceRows = await context.PeopleBaseItemMap.AsNoTracking()
+ .Where(m => sourceIds.Contains(m.ItemId) && _scoredPersonTypes.Contains(m.People.PersonType))
+ .Select(m => new { m.ItemId, m.PeopleId, m.People.PersonType })
+ .ToListAsync(cancellationToken).ConfigureAwait(false);
+
+ if (personSourceRows.Count > 0)
{
- var sourceRows = await context.PeopleBaseItemMap.AsNoTracking()
- .Where(m => sourceIds.Contains(m.ItemId) && personTypes.Contains(m.People.PersonType))
- .Select(m => new { m.ItemId, Key = m.PeopleId })
+ var allPersonIds = personSourceRows.Select(r => r.PeopleId).Distinct().ToList();
+
+ var personCandidateRows = await context.PeopleBaseItemMap.AsNoTracking()
+ .Where(m => allPersonIds.Contains(m.PeopleId))
+ .Select(m => new { m.ItemId, m.PeopleId })
.ToListAsync(cancellationToken).ConfigureAwait(false);
- var sourceMap = sourceRows.GroupBy(r => r.ItemId).ToDictionary(g => g.Key, g => g.Select(x => x.Key).ToHashSet());
- var allKeys = sourceMap.Values.SelectMany(v => v).Distinct().ToList();
- if (allKeys.Count == 0)
+ var personToCandidates = personCandidateRows
+ .GroupBy(r => r.PeopleId)
+ .ToDictionary(g => g.Key, g => g.Select(x => x.ItemId).ToList());
+
+ foreach (var weightGroup in personSourceRows.GroupBy(r => _personTypeWeights[r.PersonType!]))
{
- continue;
+ var sourceMap = weightGroup
+ .GroupBy(r => r.ItemId)
+ .ToDictionary(g => g.Key, g => g.Select(x => x.PeopleId).ToHashSet());
+ ApplyDimensionScores(sourceIds, sourceMap, personToCandidates, weightGroup.Key, result);
}
-
- var candidateRows = await context.PeopleBaseItemMap.AsNoTracking()
- .Where(m => allKeys.Contains(m.PeopleId))
- .Select(m => new { m.ItemId, Key = m.PeopleId })
- .ToListAsync(cancellationToken).ConfigureAwait(false);
-
- var keyToCandidates = candidateRows.GroupBy(r => r.Key).ToDictionary(g => g.Key, g => g.Select(x => x.ItemId).ToList());
- ApplyDimensionScores(sourceIds, sourceMap, keyToCandidates, weight, result);
}
foreach (var sourceId in sourceIds)