58 lines
2.0 KiB
C#
58 lines
2.0 KiB
C#
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using Lucene.Net.Analysis;
|
|
using Lucene.Net.Analysis.Standard;
|
|
using Lucene.Net.Documents;
|
|
using Lucene.Net.Index;
|
|
using Lucene.Net.QueryParsers;
|
|
using Lucene.Net.Search;
|
|
using Portoa.Persistence;
|
|
|
|
namespace VideoGameQuotes.Api.Search.Lucene {
|
|
/// <summary>
|
|
/// <see cref="IQuoteSearcher"/> implementation based on <c>Lucene.NET</c>
|
|
/// </summary>
|
|
public class LuceneQuoteSearcher : IQuoteSearcher {
|
|
private readonly ISearchIndexLocator indexLocator;
|
|
private readonly IRepository<Quote> quoteRepository;
|
|
private readonly Analyzer analyzer = new StandardAnalyzer();
|
|
private readonly QueryParser queryParser;
|
|
|
|
public LuceneQuoteSearcher(ISearchIndexLocator indexLocator, IRepository<Quote> quoteRepository) {
|
|
this.indexLocator = indexLocator;
|
|
this.quoteRepository = quoteRepository;
|
|
queryParser = new QueryParser("text", analyzer);
|
|
}
|
|
|
|
[UnitOfWork]
|
|
public IEnumerable<SearchResult> Search(string searchString) {
|
|
var query = queryParser.Parse(QueryParser.Escape(searchString));
|
|
var searcher = new IndexSearcher(indexLocator.IndexDirectory);
|
|
return searcher
|
|
.Search(query)
|
|
.ToEnumerable()
|
|
.Select(hit => new SearchResult {
|
|
Score = hit.GetScore(),
|
|
Quote = quoteRepository.FindById(int.Parse(hit.GetDocument().GetField("id").StringValue()))
|
|
});
|
|
}
|
|
|
|
[UnitOfWork]
|
|
public void BuildIndex(bool replaceOldIndex = true) {
|
|
var indexWriter = new IndexWriter(indexLocator.IndexDirectory, analyzer, replaceOldIndex);
|
|
foreach (var quote in quoteRepository.Records) {
|
|
indexWriter.AddDocument(CreateDocument(quote));
|
|
}
|
|
|
|
indexWriter.Optimize();
|
|
indexWriter.Close();
|
|
}
|
|
|
|
private static Document CreateDocument(Quote quote) {
|
|
var document = new Document();
|
|
document.Add(new Field("id", quote.Id.ToString(), Field.Store.YES, Field.Index.NO));
|
|
document.Add(new Field("text", quote.Text, Field.Store.YES, Field.Index.TOKENIZED));
|
|
return document;
|
|
}
|
|
}
|
|
} |