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

本文关键字:语言 分析器 net lucene search nhibernate | 更新日期: 2023-09-27 18:21:51

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

Article
-------
ID
Name

Article_CultureInfo分别为:

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

我正在使用Nhibernate.Search.Mapping来绘制字段/文档信息。我想在可能的情况下,根据语言融入词干和同义词分析等搜索功能。有没有什么方法可以在运行时指定Lucene Analyser,而不是在编译时/初始化时指定?

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

如果除了令牌之外,我还有一个对象的实例,我就可以从中获得CultureCode值,并进行相应的分析。任何想法都将不胜感激-我真的希望避免直接使用Lucene.Net,因为NHibernate.Search看起来集成得很好。

谢谢!

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

我基本上已经为这个方法做了一个变通——这是一个相当夸张的方法,但有效。

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

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

然后,这些文本被传递给我创建的自定义分析器,该分析器也可以解析文化,并可以推断出它是什么。然后,它使用SnowballFilter根据语言对文本进行词干处理。

以下是自定义IGetter实现IMultilingualContentInfoGet()方法的代码

    /// <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");
        }
    }