程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> NHibernate.Search:基於Lucene.NET的全文索引

NHibernate.Search:基於Lucene.NET的全文索引

編輯:關於.NET

NHibernate.Search現在是NHiberante Contrilb下面的一個還沒有發布的項目,也是從 Hibernate.Search移植而來,把NHibernate和Lucene.NET結合在一起,ORM持久化對象到數據庫 中,Lucene.NET提供索引及查詢支持.

下面在實際使用一下NHibernate.Search的使用:

由於這個項目還沒有發布,它的很多特性也是一直在變化,所以現在只是以我下載的版本為准,如果你想 嘗試此項目,請下載最下面的代碼,裡面包括自己編譯生成的NHibernate.Search及最新的Lucene.net相關 的dll.

一.配置 

1.修改你的NHibernate配置信息的地方,同樣添加NHibernate.Search的配置信息.

<configSections>
<section name="hibernate-configuration"  type="NHibernate.Cfg.ConfigurationSectionHandler, NHibernate"/>
<section  name="nhs-configuration" type="NHibernate.Search.Cfg.ConfigurationSectionHandler,  NHibernate.Search" 
requirePermission="false" />
<sectionGroup  name="system.web.extensions"  type="System.Web.Configuration.SystemWebExtensionsSectionGroup, 
System.Web.Extensions,  Version=3.5.0.0, Culture=neutral,  PublicKeyToken=31BF3856AD364E35">
.....
</configSections>

需要注意的是,在NHibernate.Search之前的版本中,曾經NHibernate.Search的配置信息和NHIbernate 的放在一起.接下來,我們來看下具體的配置塊:

<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
     <bytecode-provider type="lcg"/>
    <reflection-optimizer  use="true"/>
    <session-factory name="NHibernateSearch.Demo">
       <property  name="connection.provider">NHibernate.Connection.DriverConnectionProvider,  NHibernate</property>
      <property  name="connection.connection_string">
        Data  Source=|DataDirectory|Demo.db3;Version=3;Compress=False;synchronous=OFF;
       </property>
      <property name="show_sql">true</property>
      <property  name="dialect">NHibernate.Dialect.SQLiteDialect</property>
       <property  name="connection.driver_class">NHibernate.Driver.SQLite20Driver</property>
       <property name="prepare_sql">true</property>
       <property name="cache.provider_class">NHibernate.Cache.HashtableCacheProvider,  NHibernate</property>
      <property  name="cache.use_query_cache">true</property>
      <mapping  assembly="NHibernateSearch.Demo.Model"/>
    </session-factory>
   </hibernate-configuration>
 <nhs-configuration xmlns='urn:nhs-configuration- 1.0'>
    <search-factory sessionFactoryName="NHibernateSearch.Demo">
       <property  name='hibernate.search.default.directory_provider'>NHibernate.Search.Store.FSDirectoryPro vider, 
NHibernate.Search</property>
      <property  name='hibernate.search.default.indexBase'>~/Index</property>
       <property name='hibernate.search.default.indexBase.create'>true</property>
    </search-factory>
  </nhs-configuration>

上面的是NHibernate的配置信息,由於我在示例程序中使用的是SQLite數據庫,所以這個Demo也是一個 SQLite+NHibernate的案例,而且裡注意SQLite的連接字符串Data Source=|DataDirectory|Demo.db3,這樣 的話,只要把數據文件放在App_Data下面就可以運行了,而不用再去填寫數據庫文件的絕對路徑.

下面是NHibernate.Search的配置,我們采用基於文件目錄的全文檢索,索引文件放在根目錄下面的 Index文件夾下面.

另外,我們設置一下NHibernate的事件監聽(如果不我們設置的話,我們要手動去調用,才能夠使 NHibernate在持久化對象時,同時處理全文索引),現在這個事件配置還不支持直接在NHibernate這樣配 置:

<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'/> 

現在我們只能在創建SessionFactory前,手動添加這個配置信息:

Configuration configuration = new Configuration();
         configuration.SetListener(NHibernate.Event.ListenerType.PostUpdate, new  FullTextIndexEventListener());
        configuration.SetListener (NHibernate.Event.ListenerType.PostInsert, new FullTextIndexEventListener());
         configuration.SetListener(NHibernate.Event.ListenerType.PostDelete, new  FullTextIndexEventListener());
        configuration.Configure();
         sessionFactory= configuration.BuildSessionFactory();

我們為更新,刪除,添加都配置了全文索引的事件監聽,這樣就能夠保證索引文件裡的數據和實際數據庫 裡的保持一致,不要擔心,這的性能也有考慮,這裡可以支持最大提交數量,而不一定非要每條操作都去更改 索引文件.

二.使用

首先我們要在NHibernate實體對象這裡添加一些NHibernate.Search的一些關於全文索引的屬性聲明. 不知道這裡以後會不會支持xml的配置而不是修改原來的對象代碼.

[Indexed(Index = "Book")] 
  public class Book
  {
     [DocumentId]
    public virtual string BookID
    {
      get;
      set;
    }
    [Field(Index.Tokenized, Store = Store.Yes)]
    public virtual string Title
    {
      get;
       set;
    }
    [Field(Index.Tokenized, Store = Store.Yes)]
     public virtual string Authors
    {
      get;
      set;
     }
    [Field(Index.Tokenized, Store = Store.Yes)]
    public virtual  string Publisher
    {
      get;
      set;
    }
     [Field(Index.Tokenized, Store = Store.Yes)]
    public virtual string  Summary
    {
      get;
      set;
    }
  }

用過Lucene.Net的朋友們可能會發現,其實這些標識,原來在不使用NHibernate時是直接針對字段的.而 現在只是針對一個業務對象的屬性.這樣的話,但數據添加或者更改時,就會自動的進行索引,但數據進行刪 除時,也自動更新索引,而可以不進行人為的干預.

上面是一個對象Book,其中包含名稱,作者,出版社,簡介.我們要想實現對這幾個屬性進行全文檢索的話 ,以前只能夠同時拼幾個LiKE,如果針對數據庫,數據庫數據的話肯定性能不會好,但是如果針對索引文件就 不一樣了.首先我們看一下怎麼來實現搜索:

public  static IList<BookSearchResult> FindBooks(string query)
     {
      IList<BookSearchResult> results = new  List<BookSearchResult>();
      Analyzer analyzer = new  Lucene.Net.Analysis.Standard.StandardAnalyzer();
  MultiFieldQueryParser parser =  new MultiFieldQueryParser(new string[] { "Title", "Summary", "Authors",  "Publisher"
  },     analyzer);
      Query queryObj;
       try
      {
        queryObj = parser.Parse(query);
      }
      catch (ParseException)
      {
        return  results;
      }
      IFullTextSession session =  Search.CreateFullTextSession(NHibernateHelper.GetCurrentSession());
      
       ///1
      System.Type targetType = typeof(Book);
      IQuery  nhQuery = session.CreateFullTextQuery(queryObj, new Type[] { targetType });
       IList<Book> books = nhQuery.List<Book>();

       NHibernate.Cfg.Configuration cf = new Configuration().Configure();
       SearchFactoryImpl searchFactory  = SearchFactoryImpl.GetSearchFactory(cf);
       IDirectoryProvider provider = searchFactory.GetDirectoryProviders(targetType) [0];

      Workspace workspace = new Workspace(searchFactory);
       IndexReader indexReader = workspace.GetIndexReader(provider, targetType);
       Query simplifiedQuery = queryObj.Rewrite(indexReader);
       SimpleHTMLFormatter formatter = new SimpleHTMLFormatter("<b class='term'>",  "</b>");

      Highlighter hTitle = GetHighlighter(simplifiedQuery,  formatter, "Title", 100);
      Highlighter hSummary = GetHighlighter (simplifiedQuery, formatter, "Summary", 200);
      Highlighter hAuthors =  GetHighlighter(simplifiedQuery, formatter, "Authors", 100);
      Highlighter  hPublisher = GetHighlighter(simplifiedQuery, formatter, "Publisher", 100);

       foreach (Book book in books)
      {
         BookSearchResult result = new BookSearchResult(book);

        TokenStream  tsTitle = analyzer.TokenStream("Title", new System.IO.StringReader(book.Title ??  string.Empty));
        result.HighlightedTitle = hTitle.GetBestFragment (tsTitle, book.Title);

TokenStream tsAuthors = analyzer.TokenStream("Authors",  new System.IO.StringReader(book.Authors ?? string.Empty));
         result.HighlightedAuthors = hAuthors.GetBestFragment(tsAuthors, book.Authors);

  TokenStream tsPublisher = analyzer.TokenStream("Publisher", new System.IO.StringReader (book.Publisher ??
        string.Empty));
         result.HighlightedPublisher = hPublisher.GetBestFragment(tsPublisher,  book.Publisher);

TokenStream tsSummary = analyzer.TokenStream("Summary", new  System.IO.StringReader(book.Summary ?? 
string.Empty));
result.HighlightedSummary =  hSummary.GetBestFragments(tsSummary, book.Summary, 3, " ... <br /><br  /> ... ");

        results.Add(result);
      }
       return results;
    }

相信使用過Lucene.Net的朋友對上面的代碼並不難理解,所有使用IFullTextSession的操作,都會進行 全文索引的處理.另外這裡還有多字段解析和分詞的技術,就不詳細介紹了.上面還使用了對查詢關鍵字進 行高亮顯示,其中的BookSearchResult實體也只是對Book進行了包裝,進行了顯示的一些處理.具體請查看 源代碼.

你可以在上面注釋的///1處,添加對Book的一些操作,就可以顯示的查看索引文件是否也同時進行了更 新了.

二.結果

下載直接運行整個項目,輸入”程序”關鍵字,你會發現,在很短時間內,列出來了符合的記錄,並黑色顯 示匹配的字(至於與不進行索引的搜索性能對比,留給以後再做吧):

三.資料及參考

1.NHibernate.Search using Lucene.NET Full Text Index  http://blogs.intesoft.net/post/2008/03/NHibernateSearch-using-Lucene-NET-Full-Text-Index- Part1.aspx

2.NHibernate Search   http://darioquintana.com.ar/blogging/?p=21

3.Lucene.NET and NHibernate.Search on medium trust http://www.klopfenstein.net/lorenz.aspx/lucene-net-and-nhibernate-search-on-medium-trust

4.Using NHibernate.Search with ActiveRecord http://using.castleproject.org/display/AR/Using+NHibernate.Search+with+ActiveRecord

出處:http://lonely7345.cnblogs.com

本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位 置給出原文連接,否則保留追究法律責任的權利。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved