using Lucene.Net.Analysis.Standard; using Lucene.Net.Documents; using Lucene.Net.Index; using Lucene.Net.QueryParsers; using Lucene.Net.Search; using Lucene.Net.Store; using MediaBrowser.Controller; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Library; using MediaBrowser.Model.Logging; 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 LuceneSearchEngine : ILibrarySearchEngine, IDisposable { private readonly ILibraryManager _libraryManager; private readonly ILogger _logger; public LuceneSearchEngine(IServerApplicationPaths serverPaths, ILogManager logManager, ILibraryManager libraryManager) { _libraryManager = libraryManager; _logger = logManager.GetLogger("Lucene"); //string luceneDbPath = serverPaths.DataPath + "\\SearchIndexDB"; //if (!System.IO.Directory.Exists(luceneDbPath)) // System.IO.Directory.CreateDirectory(luceneDbPath); //else if(File.Exists(luceneDbPath + "\\write.lock")) // File.Delete(luceneDbPath + "\\write.lock"); //LuceneSearch.Init(luceneDbPath, _logger); //BaseItem.LibraryManager.LibraryChanged += LibraryChanged; } public void LibraryChanged(object source, ChildrenChangedEventArgs changeInformation) { Task.Run(() => { if (changeInformation.ItemsAdded.Count + changeInformation.ItemsUpdated.Count > 0) { LuceneSearch.AddUpdateLuceneIndex(changeInformation.ItemsAdded.Concat(changeInformation.ItemsUpdated)); } if (changeInformation.ItemsRemoved.Count > 0) { LuceneSearch.RemoveFromLuceneIndex(changeInformation.ItemsRemoved); } }); } public void AddItemsToIndex(IEnumerable items) { LuceneSearch.AddUpdateLuceneIndex(items); } /// /// Searches items and returns them in order of relevance. /// /// The items. /// The search term. /// IEnumerable{BaseItem}. /// searchTerm public IEnumerable Search(IEnumerable items, string searchTerm) { if (string.IsNullOrEmpty(searchTerm)) { throw new ArgumentNullException("searchTerm"); } var hits = LuceneSearch.Search(searchTerm, items.Count()); //return hits; return hits.Where(searchHit => items.Any(p => p.Id == searchHit.Id)); } public void Dispose() { //BaseItem.LibraryManager.LibraryChanged -= LibraryChanged; //LuceneSearch.CloseAll(); } /// /// Gets the search hints. /// /// The input items. /// The search term. /// IEnumerable{SearchHintResult}. /// searchTerm public async Task> GetSearchHints(IEnumerable inputItems, string 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(); hints.AddRange(items.AsParallel().Select(item => { var index = GetIndex(item.Name, searchTerm, terms); return new Tuple(item, index.Item1, index.Item2); })); // Find artists var artists = items.OfType