2012-01-27 77 views
0

我想將NHibernate.Search集成到多語言網站。現在,這個網站包含一個多語言類Article。這是通過一個獨立的課程來完成的 - Article_CultureInfo它存儲了特定於語言的內容。的Article領域是nhibernate.search/lucene.net多語言分析器

Article 
------- 
ID 
Name 

而且Article_CultureInfo是:

Article_CultureInfo 
------- 
ID 
ArticleId 
CultureCode 
PageTitle 
Content 

我使用Nhibernate.Search.Mapping繪製出現場/文件信息。我希望在可能的基礎上結合詞幹和同義詞分析等搜索功能。有什麼方法可以在運行時指定Lucene分析器,而不是編譯時間/初始化?

說我們正在分析PageTitle的內容將被存儲在各自的Lucene索引 - 這些內容可以基於CultureCode價值爲英語,法語,意大利語等。因此,分析儀應根據此值進行更改。我嘗試過實施一個自定義MultilingualAnalyser,但唯一可用的數據是要分析的字符串,即值爲PageTitle。只有那一點,我不能推斷出這種語言。 (我可以看看語言檢測技術,但這是超出範圍,因爲我已經明確知道它是什麼,並且會過度殺傷並且不是100%可靠的。)

如果我除了令牌之外,該對象的實例,我可以從中獲得CultureCode值,並據此進行分析。任何想法將不勝感激 - 我真的希望避免直接使用Lucene.Net,因爲NHibernate.Search看起來很好地集成。

謝謝!

回答

0

我基本上已經爲此方法做了一個解決方法 - 相當的矯枉過正,但工作。

我創建了IGetter的新實現,它用於多語言屬性,我稱之爲MultilingualGetter。這與BasicGetter基本相同 - 由於某種原因,我無法擴展它,因此它是sealed,所以我複製了代碼。

IGetter這樣做的是:當調用Get()方法時,會給出target對象。這是包含該屬性的類的實例。我檢查它是否實現了我創建的多語言對象的接口,IMultilingualContentInfo。然後它從IMultilingualContentInfo中檢索當前文化,並將其附加到實際文本的前面,例如[en] Hello World !.

然後將這段文本傳遞給我創建的自定義分析器,該分析器也解析文化,並且可以推斷出它是什麼。然後使用SnowballFilter來根據語言來干擾文本。

下面是自定義IGetter實施Get()方法的代碼 - IMultilingualContentInfo

/// <summary> 
    /// Gets the value of the Property from the object. 
    /// </summary> 
    /// <param name="target">The object to get the Property value from.</param> 
    /// <returns> 
    /// The value of the Property for the target. 
    /// </returns> 
    public object Get(object target) 
    { 

     if (target is IMultilingualContentInfo) 
     { 
      try 
      { 
       IMultilingualContentInfo multiLingualTarget = (IMultilingualContentInfo)target; 
       string s = (string)property.GetValue(target, new object[0]); 
       if (!string.IsNullOrWhiteSpace(s)) 
       { 
        MultilingualLuceneTextContent mlText = new MultilingualLuceneTextContent(); 
        mlText.Culture = multiLingualTarget.CultureInfo.GetCultureCode(); 
        s = mlText.GetTextIncCulture(); 

       } 
       return s; 
      } 
      catch (Exception e) 
      { 
       throw new PropertyAccessException(e, "Exception occurred", false, clazz, propertyName); 
      } 
     } 
     else 
     { 
      throw new InvalidOperationException("Multilingual Getter is only available on IMultilingualContentInfo objects"); 
     } 

    }