Дефисы в Lucene - PullRequest
       48

Дефисы в Lucene

1 голос
/ 08 апреля 2010

Я играю с Lucene и заметил, что использование дефиса (например, "полуфинал") приведет к двум словам ("полу" и "финал" в индексе. Как это должно совпадать, если пользователи ищут "полуфинал", одним словом?

Edit: я просто играю с классом StandardTokenizer, может быть, поэтому? Мне не хватает фильтра?

Спасибо!

(Edit) Мой код выглядит так:

            StandardAnalyzer sa = new StandardAnalyzer();
            TokenStream ts = sa.TokenStream("field", new StringReader("semi-final"));

            while (ts.IncrementToken())
            {
                string t = ts.ToString();
                Console.WriteLine("Token: " + t);
            }

Ответы [ 5 ]

2 голосов
/ 08 мая 2010

Я бы порекомендовал вам использовать WordDelimiterFilter от Solr (вы можете использовать его только в своем приложении Lucene в качестве TokenFilter, добавленного в ваш анализатор, просто перейдите к java-файлу для этого фильтра из Solr и добавьте его в свое приложение). 1001 *

Этот фильтр предназначен для обработки случаев так: http://wiki.apache.org/solr/AnalyzersTokenizersTokenFilters#solr.WordDelimiterFilterFactory

1 голос
/ 15 сентября 2010

Если вы ищете порт WordDelimiterFilter, то я советую Google WordDelimiter.cs, я нашел такой порт здесь:

http://osdir.com/ml/attachments/txt9jqypXvbSE.txt

Затем я создал очень простой WordDelimiterAnalyzer:

public class WordDelimiterAnalyzer: Analyzer
{
    #region Overrides of Analyzer

    public override TokenStream TokenStream(string fieldName, TextReader reader)
    {
        TokenStream result = new WhitespaceTokenizer(reader);

        result = new StandardFilter(result);
        result = new LowerCaseFilter(result);
        result = new StopFilter(true, result, StopAnalyzer.ENGLISH_STOP_WORDS_SET);
        result = new WordDelimiterFilter(result, 1, 1, 1, 1, 0);

        return result;
    }

    #endregion
}

Я сказал, что это просто:)

Если у кого-то есть реализация, я бы очень хотел ее увидеть!

1 голос
/ 08 апреля 2010

Это объяснение токенизатора в люцене

- Splits words at punctuation
   characters, removing punctuation.
   However, a dot that's not followed by
   whitespace is considered part of a
   token. 

 - Splits words at hyphens, unless
   there's a number in the token, in
   which case the whole token is
   interpreted as a product number and
   is not split.

 - Recognizes email addresses and internet hostnames as one token.

Найдено здесь

это объясняет, почему это раскалывает ваше слово.

Это, наверное, самая трудная вещь, чтобы исправить, человеческая ошибка. Если индивидуальный тип в полуфинале, это теоретически не то же самое, что поиск полуфинала. Так что, если вы хотите иметь множество слов, которые можно набирать по-разному, например:

St-Constant

Святая Константа

Saint-Constant

вы застряли с задачей иметь и святой и святой, а также дефис или не дефисен к верии. ваши токены будут огромными, и каждое слово нужно будет сравнить, чтобы увидеть, совпадают ли они.

Я все еще ищу, есть ли хороший способ приблизиться к этому, иначе, если у вас нет большого количества слов, которые вы хотите использовать, тогда сохраните и протестируйте все возможности, или сделайте цикл, который разбивает Слово начинается с первой буквы и проходит через каждую букву, разбивая строку пополам, образуя два слова, проверяя весь путь на предмет соответствия. но опять же, чей сказать, у вас есть только 2 слова. если вы проверяете более двух слов, у вас есть проблема разбить слово на несколько частей

пример

Сен-Жан-сюр-Ришелье

если я что-нибудь придумаю, я дам вам знать.

0 голосов
/ 13 июня 2011

Правило (для классического анализатора) написано в jflex:

// floating point, serial, model numbers, ip addresses, etc.
// every other segment must have at least one digit
NUM        = ({ALPHANUM} {P} {HAS_DIGIT}
           | {HAS_DIGIT} {P} {ALPHANUM}
           | {ALPHANUM} ({P} {HAS_DIGIT} {P} {ALPHANUM})+
           | {HAS_DIGIT} ({P} {ALPHANUM} {P} {HAS_DIGIT})+
           | {ALPHANUM} {P} {HAS_DIGIT} ({P} {ALPHANUM} {P} {HAS_DIGIT})+
           | {HAS_DIGIT} {P} {ALPHANUM} ({P} {HAS_DIGIT} {P} {ALPHANUM})+)

// punctuation
P            = ("_"|"-"|"/"|"."|",")
0 голосов
/ 08 апреля 2010

Вы можете написать свой собственный токенайзер, который будет генерировать для слов с дефисом все возможные комбинации токенов:

  • полуфинальный
  • полу
  • окончательный

Вам нужно будет установить правильные смещения токена, чтобы сообщить Люцену, что полуфинал и полуфинал фактически начинаются в одном и том же месте в документе.

...