2015-12-27 9 views
2

Я использую lucene 3.5 с SpanishAnalyzer (он сам использует SpanishStemmer и StandardTokenizer).
Когда SpanishAnalyzer индексирует документ со словами (например) «claramente» и «claro», они будут индексироваться как «ясность».
Это поведение понято и полезно для моих нужд, сегодня перед запросом я использую tokenStream +, чтобы получить токен моего поискового запроса и выполнить поиск, связанный с индексированным документом. Я не использую QueryParser, но строю объекты запроса lucene в коде.
однако я хочу возможность поиска точного слова (в этом примере кларо), не теряя морфологических возможностей испанского Анализера.
Я могу пропустить шаг выше (tokenStream) и искать «claro» напрямую, но он не будет найден, поскольку он индексируется как «ясность».
Также я не хочу индексировать поле дважды с помощью двух разных анализаторов, поскольку мне нужно иметь возможность использовать PhraseQuery или SpanNearQuery, содержащие одно точное слово и один регулярный термин (морфологический).
Итак ... и я догадываюсь ... Я решил изменить токенизер или стриммер или фильтр (?), Так что при индексировании времени он будет индексировать 2 токена для каждого слова, исходное и оригинальное, в этом случае «claro» и «clar», а затем при запросе я могу выбрать, использовать ли точное слово или токен.
Мне нужна помощь, чтобы понять, как (и где) я могу это сделать, я думаю, что редактирование должно быть сделано где-то в Стэммер.Lucene. индексируйте несколько токенов для каждого слова в тексте

, кстати, я сделать то же самое с древнееврейского Analyzer, который возвращает несколько маркеров для каждого слова в тексте при использовании incrementToken() (но я не исходный код)

ответ

3

Вам нужен индекс с множественный токен на позицию, потому что вы хотите искать фразы со смешанным токеном и нефиксированным (= оригинальным) токеном. Я отвечу на версию 5.3, но 3.5 не сильно отличается.

Посмотрите на исходный код ReversedWildcardFilter в solr. Вы увидите два шага на каждой лексемы:

  1. магазин текущий state с оригинальным маркером. Таким образом, первый вызов метода incrementToken() подходит к исходному токену, а второй вызов переходит к исходному токену (с той же позицией)
  2. выберите «markerChar» в качестве префикса для вставленного токена. Поэтому во время поиска вы можете решить, хотите ли вы искать с исходным или оригинальным токеном.

В случае вашего SpanishAnalyzer это будет означать, например, следующие:

Ядро SpanishAnalyzer является SpanishLightStemFilter. Испанский LightStemFilter только остановил токен с !KeywordAttribute.isKeyword(). Таким образом, для индекса-времени вставьте ключевое словоRepeatFilter в SpanishAnalyzer и отметьте отмеченный токен префиксом.

+0

Thanks, Это было очень полезно! Я не совсем понял ваше последнее предложение ... а также мой 'SpanishAnalyzer' использует' SpanishStemmer', а не 'SpanishLightStemFilter' (предположим, что они похожи), но я сделал соответствующие строки кода из' ReversedWildcardFilter' и добавил их к моему 'SnowballFilter.incrementToken()', и я теперь получаю 2 токена за каждое слово (исходное и оригинальное) –

0

Существует знак фильтр, который позволяет это довольно легко, то KeywordRepeatFilter (SpanishLightStemFilterделает уважайте KeywordAttribute). Просто добавьте это в свою цепочку анализа непосредственно перед Stemmer.Для SpanishAnalyzer, метод createComponents будет выглядеть следующим образом:

@Override 
protected TokenStreamComponents createComponents(String fieldName) { 
    final Tokenizer source; 
    if (getVersion().onOrAfter(Version.LUCENE_4_7_0)) { 
     source = new StandardTokenizer(); 
    } else { 
     source = new StandardTokenizer40(); 
    } 
    TokenStream result = new StandardFilter(source); 
    result = new LowerCaseFilter(result); 
    result = new StopFilter(result, stopwords); 
    if(!stemExclusionSet.isEmpty()) 
     result = new SetKeywordMarkerFilter(result, stemExclusionSet); 
    result = new KeywordRepeatFilter(result); 
    result = new SpanishLightStemFilter(result); 
    return new TokenStreamComponents(source, result); 
} 

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

 Смежные вопросы

  • Нет связанных вопросов^_^