aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Server.Implementations/Library/LuceneSearchEngine.cs
diff options
context:
space:
mode:
Diffstat (limited to 'MediaBrowser.Server.Implementations/Library/LuceneSearchEngine.cs')
-rw-r--r--MediaBrowser.Server.Implementations/Library/LuceneSearchEngine.cs163
1 files changed, 155 insertions, 8 deletions
diff --git a/MediaBrowser.Server.Implementations/Library/LuceneSearchEngine.cs b/MediaBrowser.Server.Implementations/Library/LuceneSearchEngine.cs
index ed085c777..d5675578d 100644
--- a/MediaBrowser.Server.Implementations/Library/LuceneSearchEngine.cs
+++ b/MediaBrowser.Server.Implementations/Library/LuceneSearchEngine.cs
@@ -1,9 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Threading.Tasks;
-using Lucene.Net.Analysis.Standard;
+using Lucene.Net.Analysis.Standard;
using Lucene.Net.Documents;
using Lucene.Net.Index;
using Lucene.Net.QueryParsers;
@@ -11,8 +6,13 @@ 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
{
@@ -22,15 +22,22 @@ namespace MediaBrowser.Server.Implementations.Library
/// </summary>
public class LuceneSearchEngine : ILibrarySearchEngine, IDisposable
{
- public LuceneSearchEngine(IServerApplicationPaths serverPaths, ILogManager logManager)
+ 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, logManager.GetLogger("Lucene"));
+ //LuceneSearch.Init(luceneDbPath, _logger);
//BaseItem.LibraryManager.LibraryChanged += LibraryChanged;
}
@@ -82,6 +89,146 @@ namespace MediaBrowser.Server.Implementations.Library
//LuceneSearch.CloseAll();
}
+
+ /// <summary>
+ /// Gets the search hints.
+ /// </summary>
+ /// <param name="inputItems">The input items.</param>
+ /// <param name="searchTerm">The search term.</param>
+ /// <returns>IEnumerable{SearchHintResult}.</returns>
+ /// <exception cref="System.ArgumentNullException">searchTerm</exception>
+ public async Task<IEnumerable<BaseItem>> GetSearchHints(IEnumerable<BaseItem> inputItems, string searchTerm)
+ {
+ if (string.IsNullOrEmpty(searchTerm))
+ {
+ throw new ArgumentNullException("searchTerm");
+ }
+
+ var hints = new List<Tuple<BaseItem, int>>();
+
+ var items = inputItems.Where(i => !(i is MusicArtist)).ToList();
+
+ foreach (var item in items)
+ {
+ var index = IndexOf(item.Name, searchTerm);
+
+ if (index != -1)
+ {
+ hints.Add(new Tuple<BaseItem, int>(item, index));
+ }
+ }
+
+ // Find artists
+ var artists = items.OfType<Audio>()
+ .SelectMany(i => new[] { i.Artist, i.AlbumArtist })
+ .Where(i => !string.IsNullOrEmpty(i))
+ .Distinct(StringComparer.OrdinalIgnoreCase)
+ .ToList();
+
+ foreach (var item in artists)
+ {
+ var index = IndexOf(item, searchTerm);
+
+ if (index != -1)
+ {
+ var artist = await _libraryManager.GetArtist(item).ConfigureAwait(false);
+
+ hints.Add(new Tuple<BaseItem, int>(artist, index));
+ }
+ }
+
+ // Find genres
+ var genres = items.SelectMany(i => i.Genres)
+ .Where(i => !string.IsNullOrEmpty(i))
+ .Distinct(StringComparer.OrdinalIgnoreCase)
+ .ToList();
+
+ foreach (var item in genres)
+ {
+ var index = IndexOf(item, searchTerm);
+
+ if (index != -1)
+ {
+ var genre = await _libraryManager.GetGenre(item).ConfigureAwait(false);
+
+ hints.Add(new Tuple<BaseItem, int>(genre, index));
+ }
+ }
+
+ // Find studios
+ var studios = items.SelectMany(i => i.Studios)
+ .Where(i => !string.IsNullOrEmpty(i))
+ .Distinct(StringComparer.OrdinalIgnoreCase)
+ .ToList();
+
+ foreach (var item in studios)
+ {
+ var index = IndexOf(item, searchTerm);
+
+ if (index != -1)
+ {
+ var studio = await _libraryManager.GetStudio(item).ConfigureAwait(false);
+
+ hints.Add(new Tuple<BaseItem, int>(studio, index));
+ }
+ }
+
+ // Find persons
+ var persons = items.SelectMany(i => i.People)
+ .Select(i => i.Name)
+ .Where(i => !string.IsNullOrEmpty(i))
+ .Distinct(StringComparer.OrdinalIgnoreCase)
+ .ToList();
+
+ foreach (var item in persons)
+ {
+ var index = IndexOf(item, searchTerm);
+
+ if (index != -1)
+ {
+ var person = await _libraryManager.GetPerson(item).ConfigureAwait(false);
+
+ hints.Add(new Tuple<BaseItem, int>(person, index));
+ }
+ }
+
+ return hints.OrderBy(i => i.Item2).Select(i => i.Item1);
+ }
+
+ /// <summary>
+ /// Gets the words.
+ /// </summary>
+ /// <param name="term">The term.</param>
+ /// <returns>System.String[][].</returns>
+ private string[] GetWords(string term)
+ {
+ // TODO: Improve this to be more accurate and respect culture
+ var words = term.Split(' ');
+
+ return words;
+ }
+
+ /// <summary>
+ /// Indexes the of.
+ /// </summary>
+ /// <param name="input">The input.</param>
+ /// <param name="term">The term.</param>
+ /// <returns>System.Int32.</returns>
+ private int IndexOf(string input, string term)
+ {
+ var index = 0;
+
+ foreach (var word in GetWords(input))
+ {
+ if (word.IndexOf(term, StringComparison.OrdinalIgnoreCase) != -1)
+ {
+ return index;
+ }
+
+ index++;
+ }
+ return -1;
+ }
}
public static class LuceneSearch