mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-06-08 08:48:48 +01:00
Implement search providers
This commit is contained in:
@@ -351,6 +351,8 @@ namespace MediaBrowser.Controller.Entities
|
||||
|
||||
public Dictionary<string, string>? HasAnyProviderId { get; set; }
|
||||
|
||||
public Dictionary<string, string[]>? HasAnyProviderIds { get; set; }
|
||||
|
||||
public Guid[] AlbumArtistIds { get; set; }
|
||||
|
||||
public Guid[] BoxSetLibraryFolders { get; set; }
|
||||
|
||||
20
MediaBrowser.Controller/Library/IExternalSearchProvider.cs
Normal file
20
MediaBrowser.Controller/Library/IExternalSearchProvider.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
|
||||
namespace MediaBrowser.Controller.Library;
|
||||
|
||||
/// <summary>
|
||||
/// Interface for external search providers that offer enhanced search capabilities.
|
||||
/// </summary>
|
||||
public interface IExternalSearchProvider : ISearchProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// Searches for items matching the query.
|
||||
/// </summary>
|
||||
/// <param name="query">The search query.</param>
|
||||
/// <param name="cancellationToken">Cancellation token.</param>
|
||||
/// <returns>Async enumerable of search results with relevance scores.</returns>
|
||||
new IAsyncEnumerable<SearchResult> SearchAsync(
|
||||
SearchProviderQuery query,
|
||||
CancellationToken cancellationToken);
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace MediaBrowser.Controller.Library;
|
||||
|
||||
/// <summary>
|
||||
/// Marker interface for internal search providers that typically query the local database directly.
|
||||
/// </summary>
|
||||
public interface IInternalSearchProvider : ISearchProvider
|
||||
{
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
using MediaBrowser.Model.Querying;
|
||||
using MediaBrowser.Model.Search;
|
||||
|
||||
namespace MediaBrowser.Controller.Library
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface ILibrarySearchEngine.
|
||||
/// </summary>
|
||||
public interface ISearchEngine
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the search hints.
|
||||
/// </summary>
|
||||
/// <param name="query">The query.</param>
|
||||
/// <returns>Task{IEnumerable{SearchHintInfo}}.</returns>
|
||||
QueryResult<SearchHintInfo> GetSearchHints(SearchQuery query);
|
||||
}
|
||||
}
|
||||
48
MediaBrowser.Controller/Library/ISearchManager.cs
Normal file
48
MediaBrowser.Controller/Library/ISearchManager.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Model.Querying;
|
||||
using MediaBrowser.Model.Search;
|
||||
|
||||
namespace MediaBrowser.Controller.Library;
|
||||
|
||||
/// <summary>
|
||||
/// Orchestrates search operations across registered search providers.
|
||||
/// </summary>
|
||||
public interface ISearchManager
|
||||
{
|
||||
/// <summary>
|
||||
/// Searches for items and returns hints suitable for autocomplete/typeahead UI.
|
||||
/// Results are ordered by relevance score from search providers.
|
||||
/// </summary>
|
||||
/// <param name="query">The search query including filters and pagination.</param>
|
||||
/// <param name="cancellationToken">Cancellation token.</param>
|
||||
/// <returns>Paginated search hints with item metadata for display.</returns>
|
||||
Task<QueryResult<SearchHintInfo>> GetSearchHintsAsync(
|
||||
SearchQuery query,
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Gets ranked search results from registered providers. Returns only item IDs and
|
||||
/// relevance scores; callers are responsible for loading items and applying user-access filtering.
|
||||
/// </summary>
|
||||
/// <param name="query">The search provider query with type/media filters.</param>
|
||||
/// <param name="cancellationToken">Cancellation token.</param>
|
||||
/// <returns>Search results containing item IDs and relevance scores.</returns>
|
||||
Task<IReadOnlyList<SearchResult>> GetSearchResultsAsync(
|
||||
SearchProviderQuery query,
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Registers search providers discovered through dependency injection.
|
||||
/// Called during application startup.
|
||||
/// </summary>
|
||||
/// <param name="providers">The search providers to register.</param>
|
||||
void AddParts(IEnumerable<ISearchProvider> providers);
|
||||
|
||||
/// <summary>
|
||||
/// Gets all registered search providers ordered by priority.
|
||||
/// </summary>
|
||||
/// <returns>The list of search providers including the SQL fallback provider.</returns>
|
||||
IReadOnlyList<ISearchProvider> GetProviders();
|
||||
}
|
||||
44
MediaBrowser.Controller/Library/ISearchProvider.cs
Normal file
44
MediaBrowser.Controller/Library/ISearchProvider.cs
Normal file
@@ -0,0 +1,44 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
|
||||
namespace MediaBrowser.Controller.Library;
|
||||
|
||||
/// <summary>
|
||||
/// Interface for search providers.
|
||||
/// </summary>
|
||||
public interface ISearchProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the name of the provider.
|
||||
/// </summary>
|
||||
string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the type of the provider.
|
||||
/// </summary>
|
||||
MetadataPluginType Type { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the priority of the provider. Lower values execute first.
|
||||
/// </summary>
|
||||
int Priority { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Searches for items matching the query.
|
||||
/// </summary>
|
||||
/// <param name="query">The search query.</param>
|
||||
/// <param name="cancellationToken">Cancellation token.</param>
|
||||
/// <returns>Ranked list of candidate item IDs with scores.</returns>
|
||||
Task<IReadOnlyList<SearchResult>> SearchAsync(
|
||||
SearchProviderQuery query,
|
||||
CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether this provider can handle the given query.
|
||||
/// </summary>
|
||||
/// <param name="query">The search query to evaluate.</param>
|
||||
/// <returns>True if this provider can search for the query; otherwise, false.</returns>
|
||||
bool CanSearch(SearchProviderQuery query);
|
||||
}
|
||||
45
MediaBrowser.Controller/Library/SearchProviderQuery.cs
Normal file
45
MediaBrowser.Controller/Library/SearchProviderQuery.cs
Normal file
@@ -0,0 +1,45 @@
|
||||
using System;
|
||||
using Jellyfin.Data.Enums;
|
||||
|
||||
namespace MediaBrowser.Controller.Library;
|
||||
|
||||
/// <summary>
|
||||
/// Query object for search providers.
|
||||
/// </summary>
|
||||
public class SearchProviderQuery
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the search term.
|
||||
/// </summary>
|
||||
public required string SearchTerm { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user ID for user-specific searches.
|
||||
/// </summary>
|
||||
public Guid? UserId { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the item types to include in the search.
|
||||
/// </summary>
|
||||
public BaseItemKind[] IncludeItemTypes { get; init; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// Gets the item types to exclude from the search.
|
||||
/// </summary>
|
||||
public BaseItemKind[] ExcludeItemTypes { get; init; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// Gets the media types to include in the search.
|
||||
/// </summary>
|
||||
public MediaType[] MediaTypes { get; init; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// Gets the maximum number of results to return.
|
||||
/// </summary>
|
||||
public int? Limit { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the parent ID to scope the search.
|
||||
/// </summary>
|
||||
public Guid? ParentId { get; init; }
|
||||
}
|
||||
60
MediaBrowser.Controller/Library/SearchResult.cs
Normal file
60
MediaBrowser.Controller/Library/SearchResult.cs
Normal file
@@ -0,0 +1,60 @@
|
||||
using System;
|
||||
|
||||
namespace MediaBrowser.Controller.Library;
|
||||
|
||||
/// <summary>
|
||||
/// Represents an item matched by a search query with its relevance score.
|
||||
/// </summary>
|
||||
public readonly struct SearchResult : IEquatable<SearchResult>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SearchResult"/> struct.
|
||||
/// </summary>
|
||||
/// <param name="itemId">The item ID.</param>
|
||||
/// <param name="score">The relevance score.</param>
|
||||
public SearchResult(Guid itemId, float score)
|
||||
{
|
||||
ItemId = itemId;
|
||||
Score = score;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the ID of the matching item.
|
||||
/// </summary>
|
||||
public Guid ItemId { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the relevance score. Higher values indicate more relevant results.
|
||||
/// </summary>
|
||||
public float Score { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Compares two <see cref="SearchResult"/> instances for equality.
|
||||
/// </summary>
|
||||
/// <param name="left">The left operand.</param>
|
||||
/// <param name="right">The right operand.</param>
|
||||
/// <returns>True if the instances are equal; otherwise, false.</returns>
|
||||
public static bool operator ==(SearchResult left, SearchResult right)
|
||||
=> left.Equals(right);
|
||||
|
||||
/// <summary>
|
||||
/// Compares two <see cref="SearchResult"/> instances for inequality.
|
||||
/// </summary>
|
||||
/// <param name="left">The left operand.</param>
|
||||
/// <param name="right">The right operand.</param>
|
||||
/// <returns>True if the instances are not equal; otherwise, false.</returns>
|
||||
public static bool operator !=(SearchResult left, SearchResult right)
|
||||
=> !left.Equals(right);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override bool Equals(object? obj)
|
||||
=> obj is SearchResult other && Equals(other);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool Equals(SearchResult other)
|
||||
=> ItemId.Equals(other.ItemId) && Score.Equals(other.Score);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override int GetHashCode()
|
||||
=> HashCode.Combine(ItemId, Score);
|
||||
}
|
||||
Reference in New Issue
Block a user