using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Library; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Querying; using MediaBrowser.Model.Search; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace MediaBrowser.Server.Implementations.Library { /// /// Class LuceneSearchEngine /// http://www.codeproject.com/Articles/320219/Lucene-Net-ultra-fast-search-for-MVC-or-WebForms /// public class SearchEngine : ISearchEngine { private readonly ILibraryManager _libraryManager; private readonly IUserManager _userManager; private readonly ILogger _logger; public SearchEngine(ILogManager logManager, ILibraryManager libraryManager, IUserManager userManager) { _libraryManager = libraryManager; _userManager = userManager; _logger = logManager.GetLogger("Lucene"); } public async Task> GetSearchHints(SearchQuery query) { var user = _userManager.GetUserById(new Guid(query.UserId)); var inputItems = user.RootFolder.GetRecursiveChildren(user, null).Where(i => !(i is ICollectionFolder)); inputItems = _libraryManager.ReplaceVideosWithPrimaryVersions(inputItems); var results = await GetSearchHints(inputItems, query).ConfigureAwait(false); // Include item types if (query.IncludeItemTypes.Length > 0) { results = results.Where(f => query.IncludeItemTypes.Contains(f.Item.GetType().Name, StringComparer.OrdinalIgnoreCase)); } var searchResultArray = results.ToArray(); results = searchResultArray; var count = searchResultArray.Length; if (query.StartIndex.HasValue) { results = results.Skip(query.StartIndex.Value); } if (query.Limit.HasValue) { results = results.Take(query.Limit.Value); } return new QueryResult { TotalRecordCount = count, Items = results.ToArray() }; } /// /// Gets the search hints. /// /// The input items. /// The query. /// IEnumerable{SearchHintResult}. /// searchTerm private Task> GetSearchHints(IEnumerable inputItems, SearchQuery query) { var searchTerm = query.SearchTerm; if (string.IsNullOrEmpty(searchTerm)) { throw new ArgumentNullException("searchTerm"); } var terms = GetWords(searchTerm); var hints = new List>(); var items = inputItems.Where(i => !(i is MusicArtist)).ToList(); if (query.IncludeMedia) { // Add search hints based on item name hints.AddRange(items.Where(i => !string.IsNullOrEmpty(i.Name)).Select(item => { var index = GetIndex(item.Name, searchTerm, terms); return new Tuple(item, index.Item1, index.Item2); })); } if (query.IncludeArtists) { // Find artists var artists = items.OfType