2012-01-27 79 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"); 
     } 

    }