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

@ -139,28 +139,19 @@ namespace MediaBrowser.Api.Movies
typeof(Trailer).Name, typeof(Trailer).Name,
//typeof(LiveTvProgram).Name //typeof(LiveTvProgram).Name
}, },
// IsMovie = true // IsMovie = true
}; };
var parentIds = string.IsNullOrWhiteSpace(request.ParentId) ? new string[] { } : new[] { request.ParentId }; var parentIds = string.IsNullOrWhiteSpace(request.ParentId) ? new string[] { } : new[] { request.ParentId };
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)
{
IncludeItemTypes = new[]
{ {
var userdata = _userDataRepository.GetUserData(user, i); typeof(Movie).Name,
return new Tuple<BaseItem, bool, DateTime>(i, userdata.Played, userdata.LastPlayedDate ?? DateTime.MinValue); //typeof(Trailer).Name,
}) //typeof(LiveTvProgram).Name
.Where(i => i.Item2) },
.OrderByDescending(i => i.Item3) // IsMovie = true
.Select(i => i.Item1) SortBy = new[] { ItemSortBy.DatePlayed, ItemSortBy.Random },
.ToList(); SortOrder = SortOrder.Descending,
Limit = 7
};
var excludeFromLiked = recentlyPlayedMovies.Take(10); var recentlyPlayedMovies = _libraryManager.GetItemList(query, parentIds).ToList();
var likedMovies = allMovies
.Select(i => var likedMovies = _libraryManager.GetItemList(new InternalItemsQuery(user)
{
IncludeItemTypes = new[]
{ {
var score = 0; typeof(Movie).Name,
var userData = _userDataRepository.GetUserData(user, i); 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()
if (userData.IsFavorite) }, parentIds);
{
score = 2;
}
else
{
score = userData.Likes.HasValue ? userData.Likes.Value ? 1 : -1 : 0;
}
return new Tuple<BaseItem, int>(i, score);
})
.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,23 +320,34 @@ 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)
foreach (var director in directors)
{ {
var items = allMovies var items = _libraryManager.GetItemList(new InternalItemsQuery(user)
.Where(i => _libraryManager.GetPeople(i).Any(p => string.Equals(p.Type, PersonType.Director, StringComparison.OrdinalIgnoreCase) && string.Equals(p.Name, director, StringComparison.OrdinalIgnoreCase))) {
.Take(itemLimit) Person = name,
.ToList(); // 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
}).DistinctBy(i => i.GetProviderId(MetadataProviders.Imdb) ?? Guid.NewGuid().ToString("N"))
.Take(itemLimit)
.ToList();
if (items.Count > 0) if (items.Count > 0)
{ {
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,20 +355,26 @@ 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"))
.Take(itemLimit)
var items = allMovies .ToList();
.Where(i => itemsWithActor.Contains(i.Id))
.Take(itemLimit)
.ToList();
if (items.Count > 0) if (items.Count > 0)
{ {

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[] { };