Remote-Search: Suppress duplicates when agregating results from multiple providers
This is a revision to pull request #1205 which tries to avoid returning duplicate results from multiple providers. Duplicates are eliminated in two stages: * Check for duplicate provider ids * In case of movies and series: Also remove duplicates by title/year combination The second stage is required because search results of themoviedb and thetvdb do not contain external ids and performing separate queries for each individual result would be too expensive. This is not an ideal solution, but Name/Year is anyway just exactly that information which is presented to the client in the results - apart from the image, of course. Images are only aggregated on matching provider ids, though. To allow image aggregation over all search results, the breaking condition once the result list is full has been removed..
This commit is contained in:
parent
e5fdf31ec4
commit
54177fbd60
|
@ -700,7 +700,7 @@ namespace MediaBrowser.Providers.Manager
|
|||
|
||||
// Manual edit occurred
|
||||
// Even if save local is off, save locally anyway if the metadata file already exists
|
||||
if (fileSaver == null || !isEnabledFor || !_fileSystem.FileExists(fileSaver.GetSavePath(item)))
|
||||
if (fileSaver == null || !isEnabledFor || !_fileSystem.FileExists(fileSaver.GetSavePath(item)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -759,6 +759,8 @@ namespace MediaBrowser.Providers.Manager
|
|||
}
|
||||
|
||||
var resultList = new List<RemoteSearchResult>();
|
||||
var foundProviderIds = new Dictionary<Tuple<string, string>, RemoteSearchResult>();
|
||||
var foundTitleYearStrings = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
foreach (var provider in providers)
|
||||
{
|
||||
|
@ -766,16 +768,50 @@ namespace MediaBrowser.Providers.Manager
|
|||
{
|
||||
var results = await GetSearchResults(provider, searchInfo.SearchInfo, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
var list = results.ToList();
|
||||
|
||||
if (list.Count > 0)
|
||||
foreach (var result in results)
|
||||
{
|
||||
resultList.AddRange(list.Take(maxResults - resultList.Count));
|
||||
}
|
||||
var bFound = false;
|
||||
|
||||
if (resultList.Count >= maxResults)
|
||||
{
|
||||
return resultList;
|
||||
// This check prevents duplicate search results by comparing provider ids
|
||||
foreach (var providerId in result.ProviderIds)
|
||||
{
|
||||
var idTuple = new Tuple<string, string>(providerId.Key.ToLower(), providerId.Value.ToLower());
|
||||
|
||||
if (!foundProviderIds.ContainsKey(idTuple))
|
||||
{
|
||||
foundProviderIds.Add(idTuple, result);
|
||||
}
|
||||
else
|
||||
{
|
||||
bFound = true;
|
||||
var existingResult = foundProviderIds[idTuple];
|
||||
if (string.IsNullOrEmpty(existingResult.ImageUrl) && !string.IsNullOrEmpty(result.ImageUrl))
|
||||
{
|
||||
existingResult.ImageUrl = result.ImageUrl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This is a workaround duplicate check for movies, where intersecting provider ids are not always available
|
||||
if (typeof(TItemType) == typeof(Movie) || typeof(TItemType) == typeof(Series))
|
||||
{
|
||||
var titleYearString = string.Format("{0} ({1})", result.Name, result.ProductionYear);
|
||||
|
||||
if (foundTitleYearStrings.Contains(titleYearString))
|
||||
{
|
||||
bFound = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
foundTitleYearStrings.Add(titleYearString);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!bFound && resultList.Count < maxResults)
|
||||
{
|
||||
resultList.Add(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
|
Loading…
Reference in New Issue
Block a user