Tutorial :NHibernate.Search with S#arp Architecture



Question:

Has anyone managed to get nhibernate.search (Lucene) to work with S#arp Architecture? I think I have it all wired up correctly except Luke shows no records or indexes when I run my indexing method. The index files for the entity are created (segments.gen & segments_1) but both are 1kb in size which explains why Luke shows no data.

I execute no other code specific to getting search to work, am I missing some initialisation calls? I assume the listeners get picked up automatically by nhibernate.

In my Web project I have:

NHibernate.config

<?xml version="1.0" encoding="utf-8" ?>  <hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">    <session-factory>      <property name="connection.connection_string">Data Source=.\SQLEXPRESS;Database=MyDatabase;Integrated Security=True;</property>      <property name="dialect">NHibernate.Dialect.MsSql2005Dialect</property>      <property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>      <property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>      <property name="show_sql">true</property>      <property name="generate_statistics">true</property>      <property name="connection.release_mode">auto</property>      <property name="adonet.batch_size">500</property>      <property name="proxyfactory.factory_class">NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle</property>        <listener class='NHibernate.Search.Event.FullTextIndexEventListener, NHibernate.Search' type='post-insert'/>      <listener class='NHibernate.Search.Event.FullTextIndexEventListener, NHibernate.Search' type='post-update'/>      <listener class='NHibernate.Search.Event.FullTextIndexEventListener, NHibernate.Search' type='post-delete'/>    </session-factory>  </hibernate-configuration>  

Web.Config

<configSections>    ...    <section name="nhs-configuration" type="NHibernate.Search.Cfg.ConfigurationSectionHandler, NHibernate.Search" requirePermission="false" />  </configSections>    <nhs-configuration xmlns='urn:nhs-configuration-1.0'>    <search-factory>      <property name="hibernate.search.default.directory_provider">NHibernate.Search.Store.FSDirectoryProvider, NHibernate.Search</property>      <property name="hibernate.search.default.indexBase">~\Lucene</property>    </search-factory>  </nhs-configuration>  

My entity is decorated as follows:

[Indexed(Index = "Posting")]   public class Posting : Entity  {      [DocumentId]      public new virtual int Id      {          get { return base.Id; }          protected set { base.Id = value; }      }        [Field(Index.Tokenized, Store = Store.Yes)]      [Analyzer(typeof(StandardAnalyzer))]      public virtual string Title { get; set; }        [Field(Index.Tokenized, Store = Store.Yes)]      [Analyzer(typeof(StandardAnalyzer))]      public virtual string Description { get; set; }        public virtual DateTime CreatedDate { get; set; }      ...  }  

And I run the following to create the index

public void BuildSearchIndex()  {      FSDirectory directory = null;      IndexWriter writer = null;        var type = typeof(Posting);        var info = new DirectoryInfo(GetIndexDirectory());        if (info.Exists)      {          info.Delete(true);      }        try      {          directory = FSDirectory.GetDirectory(Path.Combine(info.FullName, type.Name), true);          writer = new IndexWriter(directory, new StandardAnalyzer(), true);      }      finally      {          if (directory != null)          {              directory.Close();          }            if (writer != null)          {              writer.Close();          }      }        var fullTextSession = Search.CreateFullTextSession(this.Session);        // select all Posting objects from NHibernate and add them to the Lucene index      foreach (var instance in Session.CreateCriteria(typeof(Posting)).List<Posting>())      {          fullTextSession.Index(instance);      }  }    private static string GetIndexDirectory()  {      var nhsConfigCollection = CfgHelper.LoadConfiguration();      var property = nhsConfigCollection.DefaultConfiguration.Properties["hibernate.search.default.indexBase"];      var fi = new FileInfo(property);      return Path.Combine(AppDomain.CurrentDomain.BaseDirectory, fi.Name);  }  


Solution:1

Found an answer to my question so here it is in case anyone else comes by this problem.

NHS configuration in web.config contained such lines:

<property name="hibernate.search.default.directory_provider">NHibernate.Search.Store.FSDirectoryProvider, NHibernate.Search</property>  <property name="hibernate.search.default.indexBase">~\SearchIndex</property>  

First line should be removed because in this case NHS consider it as though index shares. It is known NHibernateSearch issue.

If the site is run from IIS, Network Service should have all permissions on search index directory.


Solution:2

Jordan, are you using the latest bits from NHContrib for NHibernate.Search? I just recently updated my bits and I am running into the same situation you are. It works for me on older bits, from about July. But I can't get my indexes to create either. Your config looks right, same as mine. And your indexing method looks good too.


Solution:3

Jordan, there is now an alternative to attribute based Lucene.NET mapping called FluentNHibernate.Search, this project is hosted on codeplex.

http://fnhsearch.codeplex.com/

public class BookSearchMap : DocumentMap<Book>  {      public BookSearchMap()      {          Id(p => p.BookId).Field("BookId").Bridge().Guid();          Name("Book");          Boost(500);          Analyzer<StandardAnalyzer>();            Map(x => x.Title)              .Analyzer<StandardAnalyzer>()              .Boost(500);            Map(x => x.Description)              .Boost(500)              .Name("Description")              .Store().Yes()              .Index().Tokenized();      }  }  

Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »