Многоязычный анализатор nhibernate.search / lucene.net - PullRequest
0 голосов
/ 27 января 2012

Я пытаюсь интегрировать NHibernate.Search в многоязычный веб-сайт. Теперь этот сайт содержит класс Article, который является многоязычным. Это делается с помощью отдельного класса - Article_CultureInfo, в котором хранится контент для конкретного языка. Поля Article

Article
-------
ID
Name

И Article_CultureInfo:

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

Я использую Nhibernate.Search.Mapping для отображения информации о поле / документе. Я хотел бы включить функции поиска, такие как основа и анализ синонимов, где это возможно, на основе языка. Есть ли способ указать Lucene Analyzer во время выполнения, а не во время компиляции / инициализации?

Допустим, мы анализируем содержимое PageTitle, которое должно быть сохранено в соответствующем индексе Lucene. Это может быть английский, французский, итальянский и т. Д. В зависимости от значения CultureCode. Таким образом, анализатор должен меняться в зависимости от этого значения. Я попытался реализовать пользовательский MultilingualAnalyser, однако единственные доступные мне данные - это строка для анализа, то есть значение PageTitle. Из этого только я не могу вывести язык. (Я мог бы изучить методы определения языка, но это выходит за рамки, поскольку я уже точно знаю, что это такое, и это было бы излишним, а не на 100% надежным.)

Если бы у меня помимо токенов был экземпляр объекта, я мог бы извлечь из него значение CultureCode и соответствующим образом проанализировать. Буду очень признателен за любые идеи - я действительно хочу избегать непосредственного использования Lucene.Net, поскольку NHibernate.Search выглядит очень хорошо интегрированным.

Спасибо!

1 Ответ

0 голосов
/ 31 января 2012

Я в основном обошел этот метод - довольно излишне, но работает.

Я создал новую реализацию 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");
        }

    }
...