nhibernate.search / lucene.net多语言分析器

时间:2012-01-27 13:37:59

标签: c# lucene.net multilingual nhibernate.search

我正在尝试将NHibernate.Search集成到一个多语言网站中。现在,这个网站包含一个多语言的课程Article。这是通过使用单独的类Article_CultureInfo来完成的,该类存储特定于语言的内容。 Article的字段是

Article
-------
ID
Name

Article_CultureInfo是:

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

我正在使用Nhibernate.Search.Mapping来绘制字段/文档信息。我希望根据语言结合搜索功能,如词干和同义词分析。有没有什么方法可以在运行时指定Lucene Analyzer,而不是编译时/初始化?

假设我们正在分析要存储在相应Lucene索引中的PageTitle的内容 - 此内容可以是基于CultureCode的值的英语,法语,意大利语等。因此,分析仪应根据此值进行更改。我尝试过实现自定义MultilingualAnalyser,但是我可用的唯一数据是要分析的字符串,即PageTitle的值。仅凭这一点,我无法推断出语言。 (我可以研究一下语言检测技术,但这已超出范围,因为我已经具体了解它是什么,并且过度杀伤并且不是100%可靠。)

如果我要与标记(对象的实例)分开,我可以从中获取CultureCode值,并进行相应的分析。任何想法都将非常感激 - 我真的希望避免直接使用Lucene.Net,因为NHibernate.Search看起来很好地集成。

谢谢!

1 个答案:

答案 0 :(得分:0)

我基本上已经完成了这种方法的解决方法 - 相当有点矫枉过正但是有效。

我创建了IGetter的新实现,用于多语言属性,我称之为MultilingualGetter。这与BasicGetter基本相同 - 我无法从它扩展,因为它是sealed,所以我复制了代码。

这个IGetter的作用是:当调用Get()方法时,会给它target个对象。这是包含该属性的类的实例。我检查它是否实现了我创建的多语言对象的接口IMultilingualContentInfo。然后它从IMultilingualContentInfo检索当前文化,并将其附加到实际文本的前面,例如[en] Hello World!。

然后将此文本传递给我创建的自定义分析器,该分析器也会解析文化,并可以推断出它是什么。然后使用SnowballFilter根据语言来阻止文本。

以下是自定义Get()实施的IGetter方法的代码 - 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");
        }

    }