rework movie suggestion queryies

This commit is contained in:
Luke Pulverenti 2016-05-31 14:42:32 -04:00
parent 977f62336b
commit 05fedd2b61
2 changed files with 72 additions and 63 deletions

View File

@ -146,21 +146,12 @@ namespace MediaBrowser.Api.Movies
var movies = _libraryManager.GetItemList(query, parentIds) var movies = _libraryManager.GetItemList(query, parentIds)
.OrderBy(i => (int)i.SourceType); .OrderBy(i => (int)i.SourceType);
var listEligibleForCategories = new List<BaseItem>();
var listEligibleForSuggestion = new List<BaseItem>(); var listEligibleForSuggestion = new List<BaseItem>();
var list = movies.ToList(); var list = movies.ToList();
listEligibleForCategories.AddRange(list);
listEligibleForSuggestion.AddRange(list); listEligibleForSuggestion.AddRange(list);
listEligibleForCategories = listEligibleForCategories
// Exclude trailers from the suggestion categories
.Where(i => i is Movie)
.DistinctBy(i => i.Name, StringComparer.OrdinalIgnoreCase)
.DistinctBy(i => i.GetProviderId(MetadataProviders.Imdb) ?? Guid.NewGuid().ToString(), StringComparer.OrdinalIgnoreCase)
.ToList();
listEligibleForSuggestion = listEligibleForSuggestion listEligibleForSuggestion = listEligibleForSuggestion
.DistinctBy(i => i.Name, StringComparer.OrdinalIgnoreCase) .DistinctBy(i => i.Name, StringComparer.OrdinalIgnoreCase)
.DistinctBy(i => i.GetProviderId(MetadataProviders.Imdb) ?? Guid.NewGuid().ToString(), StringComparer.OrdinalIgnoreCase) .DistinctBy(i => i.GetProviderId(MetadataProviders.Imdb) ?? Guid.NewGuid().ToString(), StringComparer.OrdinalIgnoreCase)
@ -170,7 +161,7 @@ namespace MediaBrowser.Api.Movies
dtoOptions.Fields = request.GetItemFields().ToList(); dtoOptions.Fields = request.GetItemFields().ToList();
var result = GetRecommendationCategories(user, listEligibleForCategories, listEligibleForSuggestion, request.CategoryLimit, request.ItemLimit, dtoOptions); var result = GetRecommendationCategories(user, request.ParentId, listEligibleForSuggestion, request.CategoryLimit, request.ItemLimit, dtoOptions);
return ToOptimizedResult(result); return ToOptimizedResult(result);
} }
@ -233,44 +224,43 @@ namespace MediaBrowser.Api.Movies
return result; return result;
} }
private IEnumerable<RecommendationDto> GetRecommendationCategories(User user, List<BaseItem> allMoviesForCategories, List<BaseItem> allMovies, int categoryLimit, int itemLimit, DtoOptions dtoOptions) private IEnumerable<RecommendationDto> GetRecommendationCategories(User user, string parentId, List<BaseItem> allMovies, int categoryLimit, int itemLimit, DtoOptions dtoOptions)
{ {
var categories = new List<RecommendationDto>(); var categories = new List<RecommendationDto>();
var recentlyPlayedMovies = allMoviesForCategories var parentIds = string.IsNullOrWhiteSpace(parentId) ? new string[] { } : new[] { parentId };
.Select(i => var query = new InternalItemsQuery(user)
{ {
var userdata = _userDataRepository.GetUserData(user, i); IncludeItemTypes = new[]
return new Tuple<BaseItem, bool, DateTime>(i, userdata.Played, userdata.LastPlayedDate ?? DateTime.MinValue); {
}) typeof(Movie).Name,
.Where(i => i.Item2) //typeof(Trailer).Name,
.OrderByDescending(i => i.Item3) //typeof(LiveTvProgram).Name
.Select(i => i.Item1) },
.ToList(); // IsMovie = true
SortBy = new[] { ItemSortBy.DatePlayed, ItemSortBy.Random },
SortOrder = SortOrder.Descending,
Limit = 7
};
var excludeFromLiked = recentlyPlayedMovies.Take(10); var recentlyPlayedMovies = _libraryManager.GetItemList(query, parentIds).ToList();
var likedMovies = allMovies
.Select(i =>
{
var score = 0;
var userData = _userDataRepository.GetUserData(user, i);
if (userData.IsFavorite) var likedMovies = _libraryManager.GetItemList(new InternalItemsQuery(user)
{ {
score = 2; IncludeItemTypes = new[]
}
else
{ {
score = userData.Likes.HasValue ? userData.Likes.Value ? 1 : -1 : 0; typeof(Movie).Name,
} typeof(Trailer).Name,
typeof(LiveTvProgram).Name
},
IsMovie = true,
SortBy = new[] { ItemSortBy.Random },
SortOrder = SortOrder.Descending,
Limit = 10,
IsFavoriteOrLiked = true,
ExcludeItemIds = recentlyPlayedMovies.Select(i => i.Id.ToString("N")).ToArray()
return new Tuple<BaseItem, int>(i, score); }, parentIds);
})
.OrderByDescending(i => i.Item2)
.ThenBy(i => Guid.NewGuid())
.Where(i => i.Item2 > 0)
.Select(i => i.Item1)
.Where(i => !excludeFromLiked.Contains(i));
var mostRecentMovies = recentlyPlayedMovies.Take(6).ToList(); var mostRecentMovies = recentlyPlayedMovies.Take(6).ToList();
// Get recently played directors // Get recently played directors
@ -286,8 +276,8 @@ namespace MediaBrowser.Api.Movies
var similarToRecentlyPlayed = GetSimilarTo(user, allMovies, recentlyPlayedMovies.Take(7).OrderBy(i => Guid.NewGuid()), itemLimit, dtoOptions, RecommendationType.SimilarToRecentlyPlayed).GetEnumerator(); var similarToRecentlyPlayed = GetSimilarTo(user, allMovies, recentlyPlayedMovies.Take(7).OrderBy(i => Guid.NewGuid()), itemLimit, dtoOptions, RecommendationType.SimilarToRecentlyPlayed).GetEnumerator();
var similarToLiked = GetSimilarTo(user, allMovies, likedMovies, itemLimit, dtoOptions, RecommendationType.SimilarToLikedItem).GetEnumerator(); var similarToLiked = GetSimilarTo(user, allMovies, likedMovies, itemLimit, dtoOptions, RecommendationType.SimilarToLikedItem).GetEnumerator();
var hasDirectorFromRecentlyPlayed = GetWithDirector(user, allMovies, recentDirectors, itemLimit, dtoOptions, RecommendationType.HasDirectorFromRecentlyPlayed).GetEnumerator(); var hasDirectorFromRecentlyPlayed = GetWithDirector(user, recentDirectors, itemLimit, dtoOptions, RecommendationType.HasDirectorFromRecentlyPlayed).GetEnumerator();
var hasActorFromRecentlyPlayed = GetWithActor(user, allMovies, recentActors, itemLimit, dtoOptions, RecommendationType.HasActorFromRecentlyPlayed).GetEnumerator(); var hasActorFromRecentlyPlayed = GetWithActor(user, recentActors, itemLimit, dtoOptions, RecommendationType.HasActorFromRecentlyPlayed).GetEnumerator();
var categoryTypes = new List<IEnumerator<RecommendationDto>> var categoryTypes = new List<IEnumerator<RecommendationDto>>
{ {
@ -330,14 +320,25 @@ namespace MediaBrowser.Api.Movies
return categories.OrderBy(i => i.RecommendationType).ThenBy(i => Guid.NewGuid()); return categories.OrderBy(i => i.RecommendationType).ThenBy(i => Guid.NewGuid());
} }
private IEnumerable<RecommendationDto> GetWithDirector(User user, List<BaseItem> allMovies, IEnumerable<string> directors, int itemLimit, DtoOptions dtoOptions, RecommendationType type) private IEnumerable<RecommendationDto> GetWithDirector(User user, IEnumerable<string> names, int itemLimit, DtoOptions dtoOptions, RecommendationType type)
{ {
var userId = user.Id; foreach (var name in names)
{
var items = _libraryManager.GetItemList(new InternalItemsQuery(user)
{
Person = name,
// Account for duplicates by imdb id, since the database doesn't support this yet
Limit = itemLimit + 2,
PersonTypes = new[] { PersonType.Director },
IncludeItemTypes = new[]
{
typeof(Movie).Name,
typeof(Trailer).Name,
typeof(LiveTvProgram).Name
},
IsMovie = true
foreach (var director in directors) }).DistinctBy(i => i.GetProviderId(MetadataProviders.Imdb) ?? Guid.NewGuid().ToString("N"))
{
var items = allMovies
.Where(i => _libraryManager.GetPeople(i).Any(p => string.Equals(p.Type, PersonType.Director, StringComparison.OrdinalIgnoreCase) && string.Equals(p.Name, director, StringComparison.OrdinalIgnoreCase)))
.Take(itemLimit) .Take(itemLimit)
.ToList(); .ToList();
@ -345,8 +346,8 @@ namespace MediaBrowser.Api.Movies
{ {
yield return new RecommendationDto yield return new RecommendationDto
{ {
BaselineItemName = director, BaselineItemName = name,
CategoryId = director.GetMD5().ToString("N"), CategoryId = name.GetMD5().ToString("N"),
RecommendationType = type, RecommendationType = type,
Items = _dtoService.GetBaseItemDtos(items, dtoOptions, user).ToArray() Items = _dtoService.GetBaseItemDtos(items, dtoOptions, user).ToArray()
}; };
@ -354,18 +355,24 @@ namespace MediaBrowser.Api.Movies
} }
} }
private IEnumerable<RecommendationDto> GetWithActor(User user, List<BaseItem> allMovies, IEnumerable<string> names, int itemLimit, DtoOptions dtoOptions, RecommendationType type) private IEnumerable<RecommendationDto> GetWithActor(User user, IEnumerable<string> names, int itemLimit, DtoOptions dtoOptions, RecommendationType type)
{ {
foreach (var name in names) foreach (var name in names)
{ {
var itemsWithActor = _libraryManager.GetItemIds(new InternalItemsQuery(user) var items = _libraryManager.GetItemList(new InternalItemsQuery(user)
{ {
Person = name Person = name,
// Account for duplicates by imdb id, since the database doesn't support this yet
Limit = itemLimit + 2,
IncludeItemTypes = new[]
{
typeof(Movie).Name,
typeof(Trailer).Name,
typeof(LiveTvProgram).Name
},
IsMovie = true
}); }).DistinctBy(i => i.GetProviderId(MetadataProviders.Imdb) ?? Guid.NewGuid().ToString("N"))
var items = allMovies
.Where(i => itemsWithActor.Contains(i.Id))
.Take(itemLimit) .Take(itemLimit)
.ToList(); .ToList();

View File

@ -53,6 +53,7 @@ namespace MediaBrowser.Controller.Entities
public string Person { get; set; } public string Person { get; set; }
public string[] PersonIds { get; set; } public string[] PersonIds { get; set; }
public string[] ItemIds { get; set; } public string[] ItemIds { get; set; }
public string[] ExcludeItemIds { get; set; }
public string AdjacentTo { get; set; } public string AdjacentTo { get; set; }
public string[] PersonTypes { get; set; } public string[] PersonTypes { get; set; }
@ -166,6 +167,7 @@ namespace MediaBrowser.Controller.Entities
PersonIds = new string[] { }; PersonIds = new string[] { };
ChannelIds = new string[] { }; ChannelIds = new string[] { };
ItemIds = new string[] { }; ItemIds = new string[] { };
ExcludeItemIds = new string[] { };
AncestorIds = new string[] { }; AncestorIds = new string[] { };
TopParentIds = new string[] { }; TopParentIds = new string[] { };
ExcludeTags = new string[] { }; ExcludeTags = new string[] { };