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