diff --git a/Src/VideoGameQuotes.Api/Search/IQuoteSearcher.cs b/Src/VideoGameQuotes.Api/Search/IQuoteSearcher.cs
deleted file mode 100644
index 32bb933..0000000
--- a/Src/VideoGameQuotes.Api/Search/IQuoteSearcher.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-using System.Collections.Generic;
-
-namespace VideoGameQuotes.Api.Search {
- ///
- /// Exposes an interface to search for quotes
- ///
- public interface IQuoteSearcher {
- ///
- /// Searches for quote based on the given search query
- ///
- IEnumerable Search(string query);
-
- ///
- /// (Re)builds the search index
- ///
- /// Set to false to not overwrite the old index with a brand new one.
- void BuildIndex(bool replaceOldIndex = true);
- }
-}
\ No newline at end of file
diff --git a/Src/VideoGameQuotes.Api/Search/ISearchIndexBuilder.cs b/Src/VideoGameQuotes.Api/Search/ISearchIndexBuilder.cs
deleted file mode 100644
index e45b1a8..0000000
--- a/Src/VideoGameQuotes.Api/Search/ISearchIndexBuilder.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-namespace VideoGameQuotes.Api.Search {
- ///
- /// Exposes an interface to build and update a search index
- ///
- public interface ISearchIndexBuilder {
- ///
- /// (Re)builds the search index
- ///
- void BuildIndex();
-
- ///
- /// Updates the index for the specified
- ///
- /// The object that needs its index updated
- void UpdateIndex(T indexableObject);
- }
-}
\ No newline at end of file
diff --git a/Src/VideoGameQuotes.Api/Search/ISearchIndexLocator.cs b/Src/VideoGameQuotes.Api/Search/ISearchIndexLocator.cs
deleted file mode 100644
index c12380c..0000000
--- a/Src/VideoGameQuotes.Api/Search/ISearchIndexLocator.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-namespace VideoGameQuotes.Api.Search {
- public interface ISearchIndexLocator {
- string IndexDirectory { get; }
- }
-
- public class SearchIndexLocator : ISearchIndexLocator {
- private readonly string indexDirectory;
-
- public SearchIndexLocator(string indexDirectory) {
- this.indexDirectory = indexDirectory;
- }
-
- public string IndexDirectory { get { return indexDirectory; } }
- }
-}
\ No newline at end of file
diff --git a/Src/VideoGameQuotes.Api/Search/ISearcher.cs b/Src/VideoGameQuotes.Api/Search/ISearcher.cs
deleted file mode 100644
index e75e8f8..0000000
--- a/Src/VideoGameQuotes.Api/Search/ISearcher.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using System.Collections.Generic;
-
-namespace VideoGameQuotes.Api.Search {
- ///
- /// Exposes an interface to perform a full-text search
- ///
- public interface ISearcher {
- ///
- /// Searches for records based on the given search query
- ///
- /// The search term(s) to search for
- /// The maximum number of results to return (0 is unlimited); the default is 10
- IEnumerable> Search(string query, int maxResults = 10);
- }
-}
\ No newline at end of file
diff --git a/Src/VideoGameQuotes.Api/Search/Lucene/ILuceneDocumentHandler.cs b/Src/VideoGameQuotes.Api/Search/Lucene/ILuceneDocumentHandler.cs
deleted file mode 100644
index bd1b778..0000000
--- a/Src/VideoGameQuotes.Api/Search/Lucene/ILuceneDocumentHandler.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-using Lucene.Net.Documents;
-using Lucene.Net.Index;
-
-namespace VideoGameQuotes.Api.Search.Lucene {
- public interface ILuceneDocumentHandler {
- Document BuildDocument(T source);
- Term GetIdTerm(T source);
- }
-}
\ No newline at end of file
diff --git a/Src/VideoGameQuotes.Api/Search/Lucene/LuceneEntityIndexBuilder.cs b/Src/VideoGameQuotes.Api/Search/Lucene/LuceneEntityIndexBuilder.cs
deleted file mode 100644
index 382cea2..0000000
--- a/Src/VideoGameQuotes.Api/Search/Lucene/LuceneEntityIndexBuilder.cs
+++ /dev/null
@@ -1,45 +0,0 @@
-using Lucene.Net.Index;
-using Portoa.Logging;
-using Portoa.Persistence;
-using VideoGameQuotes.Api.Persistence;
-
-namespace VideoGameQuotes.Api.Search.Lucene {
- public class LuceneEntityIndexBuilder : ISearchIndexBuilder where T : Entity {
- private readonly ILogger logger;
- private readonly IndexWriter indexWriter;
- private readonly ISearchService searchService;
- private readonly ILuceneDocumentHandler documentHandler;
-
- public LuceneEntityIndexBuilder(IndexWriter indexWriter, ISearchService searchService, ILuceneDocumentHandler documentHandler, ILogger logger) {
- this.indexWriter = indexWriter;
- this.searchService = searchService;
- this.documentHandler = documentHandler;
- this.logger = logger;
- }
-
- public void BuildIndex() {
- logger.Info("Building lucene index");
- foreach (var quote in searchService.GetAllIndexableRecords()) {
- indexWriter.AddDocument(documentHandler.BuildDocument(quote));
- }
-
- indexWriter.Optimize();
- indexWriter.Commit();
- logger.Info("Finished building lucene index");
- }
-
- public void UpdateIndex(T entity) {
- if (entity.IsTransient()) {
- throw new SearchIndexException(string.Format("Cannot add a transient entity to the index ({0})", entity));
- }
-
- logger.Info(string.Format("Updating index for {0}", entity));
- //delete current document, if it exists
- indexWriter.DeleteDocuments(documentHandler.GetIdTerm(entity));
- indexWriter.AddDocument(documentHandler.BuildDocument(entity));
-
- indexWriter.Commit();
- logger.Info(string.Format("Finished updating index for {0}", entity));
- }
- }
-}
\ No newline at end of file
diff --git a/Src/VideoGameQuotes.Api/Search/Lucene/LuceneEntitySearcher.cs b/Src/VideoGameQuotes.Api/Search/Lucene/LuceneEntitySearcher.cs
deleted file mode 100644
index 39b8d44..0000000
--- a/Src/VideoGameQuotes.Api/Search/Lucene/LuceneEntitySearcher.cs
+++ /dev/null
@@ -1,50 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using Lucene.Net.QueryParsers;
-using Lucene.Net.Search;
-using Portoa.Persistence;
-using VideoGameQuotes.Api.Persistence;
-using Directory = Lucene.Net.Store.Directory;
-
-namespace VideoGameQuotes.Api.Search.Lucene {
- ///
- /// implementation for entities based on Lucene.NET
- ///
- public class LuceneEntitySearcher : ISearcher where T : Entity {
- private readonly QueryParser queryParser;
- private readonly Directory indexDirectory;
- private readonly ISearchService searchService;
-
- public LuceneEntitySearcher(QueryParser queryParser, Directory indexDirectory, ISearchService searchService) {
- this.queryParser = queryParser;
- this.indexDirectory = indexDirectory;
- this.searchService = searchService;
- }
-
- public IEnumerable> Search(string searchString, int maxResults = 10) {
- if (string.IsNullOrWhiteSpace(searchString)) {
- return Enumerable.Empty>();
- }
- if (maxResults < 0) {
- throw new ArgumentOutOfRangeException("maxResults", maxResults, "Maximum number of results must be greater than or equal to zero");
- }
- if (maxResults == 0) {
- maxResults = int.MaxValue;
- }
-
- var query = queryParser.Parse(QueryParser.Escape(searchString));
- var searcher = new IndexSearcher(indexDirectory, true);
- try {
- var docs = searcher
- .Search(query, maxResults)
- .scoreDocs;
-
- var quotes = searchService.FindByIds(docs.Select(doc => int.Parse(searcher.Doc(doc.doc).GetField("id").StringValue())));
- return quotes.Zip(docs, (entity, doc) => new SearchResult { Entity = entity, Score = doc.score }).ToArray();
- } finally {
- searcher.Close();
- }
- }
- }
-}
\ No newline at end of file
diff --git a/Src/VideoGameQuotes.Api/Search/Lucene/LuceneExtensions.cs b/Src/VideoGameQuotes.Api/Search/Lucene/LuceneExtensions.cs
deleted file mode 100644
index 533e73c..0000000
--- a/Src/VideoGameQuotes.Api/Search/Lucene/LuceneExtensions.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using System.Collections.Generic;
-using Lucene.Net.Search;
-
-namespace VideoGameQuotes.Api.Search.Lucene {
- public static class LuceneExtensions {
- public static IEnumerable ToEnumerable(this Hits hits) {
- var iterator = hits.Iterator();
- while (iterator.MoveNext()) {
- yield return (Hit)iterator.Current;
- }
- }
- }
-}
\ No newline at end of file
diff --git a/Src/VideoGameQuotes.Api/Search/Lucene/LuceneQuoteSearcher.cs b/Src/VideoGameQuotes.Api/Search/Lucene/LuceneQuoteSearcher.cs
deleted file mode 100644
index 8f73536..0000000
--- a/Src/VideoGameQuotes.Api/Search/Lucene/LuceneQuoteSearcher.cs
+++ /dev/null
@@ -1,62 +0,0 @@
-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 {
- ///
- /// implementation based on Lucene.NET
- ///
- public class LuceneQuoteSearcher : IQuoteSearcher {
- private readonly ISearchIndexLocator indexLocator;
- private readonly IRepository quoteRepository;
- private readonly Analyzer analyzer = new StandardAnalyzer();
- private readonly QueryParser queryParser;
-
- public LuceneQuoteSearcher(ISearchIndexLocator indexLocator, IRepository quoteRepository) {
- this.indexLocator = indexLocator;
- this.quoteRepository = quoteRepository;
- queryParser = new QueryParser("text", analyzer);
- }
-
- [UnitOfWork]
- public IEnumerable Search(string searchString) {
- if (string.IsNullOrWhiteSpace(searchString)) {
- return Enumerable.Empty();
- }
-
- 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;
- }
- }
-}
\ No newline at end of file
diff --git a/Src/VideoGameQuotes.Api/Search/SearchIndexException.cs b/Src/VideoGameQuotes.Api/Search/SearchIndexException.cs
deleted file mode 100644
index ad275c4..0000000
--- a/Src/VideoGameQuotes.Api/Search/SearchIndexException.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-using System;
-
-namespace VideoGameQuotes.Api.Search {
- ///
- /// Raised when an error occurs while reading/writing a search index
- ///
- public class SearchIndexException : Exception {
- public SearchIndexException(string message = null, Exception innerException = null) : base(message, innerException) { }
- }
-}
\ No newline at end of file
diff --git a/Src/VideoGameQuotes.Api/Search/SearchResult.cs b/Src/VideoGameQuotes.Api/Search/SearchResult.cs
deleted file mode 100644
index 1605de8..0000000
--- a/Src/VideoGameQuotes.Api/Search/SearchResult.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-namespace VideoGameQuotes.Api.Search {
- ///
- /// Represents a search result
- ///
- public class SearchResult {
- ///
- /// A value (between 0 and 1, the higher the better) representing how good
- /// the match is between the search query and the value
- ///
- public double Score { get; set; }
-
- ///
- /// The matched quote
- ///
- public T Entity { get; set; }
- }
-}
\ No newline at end of file
diff --git a/Src/VideoGameQuotes.Api/VideoGameQuotes.Api.csproj b/Src/VideoGameQuotes.Api/VideoGameQuotes.Api.csproj
index 409d4a8..2d55f47 100644
--- a/Src/VideoGameQuotes.Api/VideoGameQuotes.Api.csproj
+++ b/Src/VideoGameQuotes.Api/VideoGameQuotes.Api.csproj
@@ -37,9 +37,6 @@
..\..\Lib\log4net.dll
-
- ..\..\Lib\Lucene.Net.dll
-
..\..\Lib\MySql.Data.dll
@@ -69,13 +66,6 @@
-
-
-
-
-
-
-
@@ -85,9 +75,6 @@
-
-
-
diff --git a/Src/VideoGameQuotes.Web/Configuration/UpdateSearchIndexCallHandler.cs b/Src/VideoGameQuotes.Web/Configuration/UpdateSearchIndexCallHandler.cs
index 9f1e141..b655e3b 100644
--- a/Src/VideoGameQuotes.Web/Configuration/UpdateSearchIndexCallHandler.cs
+++ b/Src/VideoGameQuotes.Web/Configuration/UpdateSearchIndexCallHandler.cs
@@ -4,8 +4,8 @@ using System.Reflection;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.InterceptionExtension;
using Portoa.Persistence;
+using Portoa.Search;
using VideoGameQuotes.Api;
-using VideoGameQuotes.Api.Search;
namespace VideoGameQuotes.Web.Configuration {
diff --git a/Src/VideoGameQuotes.Web/Controllers/QuoteController.cs b/Src/VideoGameQuotes.Web/Controllers/QuoteController.cs
index e5ef905..c07ef69 100644
--- a/Src/VideoGameQuotes.Web/Controllers/QuoteController.cs
+++ b/Src/VideoGameQuotes.Web/Controllers/QuoteController.cs
@@ -1,15 +1,14 @@
using System;
-using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Web.Mvc;
using Portoa.Persistence;
+using Portoa.Search;
using Portoa.Validation.DataAnnotations;
using Portoa.Web;
using Portoa.Web.Controllers;
using Portoa.Web.Results;
using VideoGameQuotes.Api;
-using VideoGameQuotes.Api.Search;
using VideoGameQuotes.Web.Models;
using VideoGameQuotes.Web.Security;
using VideoGameQuotes.Web.Services;
diff --git a/Src/VideoGameQuotes.Web/Global.asax.cs b/Src/VideoGameQuotes.Web/Global.asax.cs
index facc9b5..390a4ab 100644
--- a/Src/VideoGameQuotes.Web/Global.asax.cs
+++ b/Src/VideoGameQuotes.Web/Global.asax.cs
@@ -13,7 +13,9 @@ using Lucene.Net.Util;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.InterceptionExtension;
using Portoa.Logging;
+using Portoa.Lucene;
using Portoa.Persistence;
+using Portoa.Search;
using Portoa.Web;
using Portoa.Web.Models;
using Portoa.Web.Security;
@@ -21,11 +23,10 @@ using Portoa.Web.Unity;
using UnityGenerics;
using VideoGameQuotes.Api;
using VideoGameQuotes.Api.Persistence;
-using VideoGameQuotes.Api.Search;
-using VideoGameQuotes.Api.Search.Lucene;
using VideoGameQuotes.Web.Configuration;
using VideoGameQuotes.Web.Controllers;
using VideoGameQuotes.Web.Models;
+using VideoGameQuotes.Web.Search;
using VideoGameQuotes.Web.Security;
using VideoGameQuotes.Web.Services;
using Directory = Lucene.Net.Store.Directory;
diff --git a/Src/VideoGameQuotes.Web/Models/SearchModel.cs b/Src/VideoGameQuotes.Web/Models/SearchModel.cs
index e178701..de69021 100644
--- a/Src/VideoGameQuotes.Web/Models/SearchModel.cs
+++ b/Src/VideoGameQuotes.Web/Models/SearchModel.cs
@@ -1,6 +1,6 @@
using System.Collections.Generic;
+using Portoa.Search;
using VideoGameQuotes.Api;
-using VideoGameQuotes.Api.Search;
namespace VideoGameQuotes.Web.Models {
public class SearchModel {
diff --git a/Src/VideoGameQuotes.Api/Search/Lucene/QuoteDocumentHandler.cs b/Src/VideoGameQuotes.Web/Search/QuoteDocumentHandler.cs
similarity index 82%
rename from Src/VideoGameQuotes.Api/Search/Lucene/QuoteDocumentHandler.cs
rename to Src/VideoGameQuotes.Web/Search/QuoteDocumentHandler.cs
index 87c7354..eefcb08 100644
--- a/Src/VideoGameQuotes.Api/Search/Lucene/QuoteDocumentHandler.cs
+++ b/Src/VideoGameQuotes.Web/Search/QuoteDocumentHandler.cs
@@ -1,9 +1,10 @@
using Lucene.Net.Documents;
using Lucene.Net.Index;
+using Portoa.Lucene;
+using VideoGameQuotes.Api;
-namespace VideoGameQuotes.Api.Search.Lucene {
+namespace VideoGameQuotes.Web.Search {
public class QuoteDocumentHandler : ILuceneDocumentHandler {
-
public Document BuildDocument(Quote quote) {
var document = new Document();
document.Add(new Field("id", quote.Id.ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED));
diff --git a/Src/VideoGameQuotes.Api/Persistence/SearchService.cs b/Src/VideoGameQuotes.Web/Search/SearchService.cs
similarity index 70%
rename from Src/VideoGameQuotes.Api/Persistence/SearchService.cs
rename to Src/VideoGameQuotes.Web/Search/SearchService.cs
index d54b9c6..e442451 100644
--- a/Src/VideoGameQuotes.Api/Persistence/SearchService.cs
+++ b/Src/VideoGameQuotes.Web/Search/SearchService.cs
@@ -1,13 +1,9 @@
using System.Collections.Generic;
using System.Linq;
using Portoa.Persistence;
+using Portoa.Search;
-namespace VideoGameQuotes.Api.Persistence {
-
- public interface ISearchService where T : Entity {
- IEnumerable FindByIds(IEnumerable ids);
- IEnumerable GetAllIndexableRecords();
- }
+namespace VideoGameQuotes.Web.Search {
public class SearchService : ISearchService where T : Entity {
private readonly IRepository repository;
@@ -18,7 +14,6 @@ namespace VideoGameQuotes.Api.Persistence {
[UnitOfWork]
public IEnumerable FindByIds(IEnumerable ids) {
-
return repository
.Records
.Where(entity => ids.ToArray().Contains(entity.Id));
diff --git a/Src/VideoGameQuotes.Web/VideoGameQuotes.Web.csproj b/Src/VideoGameQuotes.Web/VideoGameQuotes.Web.csproj
index a3c553c..aa1bd91 100644
--- a/Src/VideoGameQuotes.Web/VideoGameQuotes.Web.csproj
+++ b/Src/VideoGameQuotes.Web/VideoGameQuotes.Web.csproj
@@ -49,6 +49,7 @@
..\..\Lib\Portoa.Log4Net.dll
+
False
..\..\Lib\Portoa.NHibernate.dll
@@ -57,8 +58,6 @@
..\..\Lib\Portoa.Web.dll
-
-
@@ -68,23 +67,15 @@
3.5
-
- 3.5
-
-
- 3.5
-
3.5
-
-
..\..\Lib\UnityGenerics.dll
@@ -101,6 +92,8 @@
+
+
diff --git a/Src/VideoGameQuotes.Web/Views/Quote/Search.aspx b/Src/VideoGameQuotes.Web/Views/Quote/Search.aspx
index d3f1d6f..8f16979 100644
--- a/Src/VideoGameQuotes.Web/Views/Quote/Search.aspx
+++ b/Src/VideoGameQuotes.Web/Views/Quote/Search.aspx
@@ -8,7 +8,7 @@
<%
foreach (var result in Model.Results) {
- Html.RenderPartial("SingleQuote", new QuoteModel {Quote = result.Entity, User = Model.User });
+ Html.RenderPartial("SingleQuote", new QuoteModel { Quote = result.Record, User = Model.User });
}
%>
\ No newline at end of file