2014-09-03 2 views
2

Я добавляю текстовый лемматизер в Solr. Мне нужно обработать весь текст, потому что контекст в лемматизации важен.Проблемы с Solr Tokenizer, добавление lemmatizer

Я получаю этот код на Интернете, и я изменил немного

http://grokbase.com/t/lucene/solr-user/138d0qn4v0/issue-with-custom-tokenizer

Я добавил наш лемматизатор, и я изменил эту линию

endOffset = word.length(); 

для этого

endOffset = startOffset + word.length(); 

сейчас если я использую Solr Admin analisys, у меня нет проблем с индексом или Q uery. Я пишу фразу, и когда я анализирую значения, результаты - это текст, хорошо помеченный.

Проблемы возникают, когда я делаю запросы в разделе «Запрос» и когда я индексирую документы. Проверка debugquery Я вижу это. Если я попрошу «korrikan» текст (означает «работает») в «naiz_body», текст хорошо легматизируется.

<str name="rawquerystring">naiz_body:"korrikan"</str> 
<str name="querystring">naiz_body:"korrikan"</str> 
<str name="parsedquery">naiz_body:korrika</str> 
<str name="parsedquery_toString">naiz_body:korrika</str> 

Теперь, если в данный момент я попросить «jolasten» текст (означает «играть») текст не lemmatized, а parsedquery и parsedquery_toString не изменяется.

<str name="rawquerystring">naiz_body:"jolasten"</str> 
<str name="querystring">naiz_body:"jolasten"</str> 
<str name="parsedquery">naiz_body:korrika</str> 
<str name="parsedquery_toString">naiz_body:korrika</str> 

Если я жду немного (или, если я перестану Solr и я бегу его), и я прошу «jolasten» текст я получаю текст хорошо lemmatized

<str name="rawquerystring">naiz_body:"jolasten"</str> 
<str name="querystring">naiz_body:"jolasten"</str> 
<str name="parsedquery">naiz_body:jolastu</str> 
<str name="parsedquery_toString">naiz_body:jolastu</str> 

Почему?

Вот код:

package eu.solr.analysis; 

import java.io.IOException; 
import java.io.Reader; 
import java.util.ArrayList; 
import java.util.List; 

import eu.solr.analysis.Lemmatizer; 

import org.apache.lucene.analysis.Tokenizer; 
import org.apache.lucene.analysis.Token; 
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute; 
import org.apache.lucene.analysis.tokenattributes.OffsetAttribute; 
import org.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute; 

public class LemmatizerTokenizer extends Tokenizer { 
    private Lemmatizer lemmatizer = new Lemmatizer(); 
    private List<Token> tokenList = new ArrayList<Token>(); 
    int tokenCounter = -1; 

    private final CharTermAttribute termAtt = addAttribute(CharTermAttribute.class); 
    private final OffsetAttribute offsetAttribute = (OffsetAttribute)addAttribute(OffsetAttribute.class); 
    private final PositionIncrementAttribute position = (PositionIncrementAttribute)addAttribute(PositionIncrementAttribute.class); 

    public LemmatizerTokenizer(AttributeFactory factory, Reader reader) { 
     super(factory, reader); 
     System.out.println("### Lemmatizer Tokenizer ###"); 
     String textToProcess = null; 
     try { 
      textToProcess = readFully(reader); 
      processText(textToProcess); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

    public String readFully(Reader reader) throws IOException { 
     char[] arr = new char[8 * 1024]; // 8K at a time 
     StringBuffer buf = new StringBuffer(); 
     int numChars; 
     while ((numChars = reader.read(arr, 0, arr.length)) > 0) { 
      buf.append(arr, 0, numChars); 
     } 
     System.out.println("### Read Fully ### => " + buf.toString()); 
     return lemmatizer.getLemma(buf.toString()); 
    } 

    public void processText(String textToProcess) { 
     System.out.println("### Process Text ### => " + textToProcess); 
     String wordsList[] = textToProcess.split(" "); 
     int startOffset = 0, endOffset = 0; 
     for (String word : wordsList) { 
      endOffset = startOffset + word.length(); 
      Token aToken = new Token(word, startOffset, endOffset); 
      aToken.setPositionIncrement(1); 
      tokenList.add(aToken); 
      startOffset = endOffset + 1; 
     } 
    } 

    @Override 
    public boolean incrementToken() throws IOException { 
     clearAttributes(); 
     tokenCounter++; 
     System.out.println("### Increment Token ###"); 
     System.out.println("Token Counter => " + tokenCounter); 
     System.out.println("TokenList size => " + tokenList.size()); 
     if (tokenCounter < tokenList.size()) { 
      Token aToken = tokenList.get(tokenCounter); 
      System.out.println("Increment Token => " + aToken.toString()); 
      termAtt.append(aToken); 
      termAtt.setLength(aToken.length()); 
      offsetAttribute.setOffset(correctOffset(aToken.startOffset()), 
      correctOffset(aToken.endOffset())); 
      position.setPositionIncrement(aToken.getPositionIncrement()); 
      return true; 
     } 
     return false; 
    } 

    @Override 
    public void close() throws IOException { 
     System.out.println("### Close ###"); 
     super.close(); 
    } 

    @Override 
    public void end() throws IOException { 
     // setting final offset 
     System.out.println("### End ###"); 
     super.end(); 
    } 

    @Override 
    public void reset() throws IOException { 
     System.out.println("### Reset ###"); 
     tokenCounter = -1; 
     super.reset(); 
    } 
} 

Спасибо всем!

редактировать:

ответ @ Alexandre-rafalovitch экран анализа в администратора UI работает хорошо. Если я делаю запрос или индексный текст, текст хорошо лексируется. Проблема заключается в пользовательском интерфейсе запросов. Если я сделаю запрос, сначала вызовет lemmatizer, но второй, похоже, использует буферизованный первый лемматированный текст и вызывает непосредственно incrementToken. Смотрите вывод кода, когда я делаю это запросы: В Analysis UI, если я запрашиваю для Korrikan, а затем для Jolasten Он выдает это:

## BasqueLemmatizerTokenizer create 
### BasqueLemmatizer Tokenizer ### 
### Read Fully ### => korrikan 
### Eustagger OUT ### => korrika 
### Process Text ### => korrika 
### Reset ### 
### Increment Token ### 
Token Counter => 0 
TokenList size => 1 
Increment Token => korrika 
### Increment Token ### 
Token Counter => 1 
TokenList size => 1 

## BasqueLemmatizerTokenizer create 
### BasqueLemmatizer Tokenizer ### 
### Read Fully ### => Jolasten 
### Eustagger OUT ### => jolastu 
### Process Text ### => jolastu 
### Reset ### 
### Increment Token ### 
Token Counter => 0 
TokenList size => 1 
Increment Token => jolastu 
### Increment Token ### 
Token Counter => 1 
TokenList size => 1 

Если я сделать этот запрос в Query UI выводит это:

## BasqueLemmatizerTokenizer create 
### BasqueLemmatizer Tokenizer ### 
### Read Fully ### => korrikan 
### Eustagger OUT ### => korrika 
### Process Text ### => korrika 
### Reset ### 
### Increment Token ### 
Token Counter => 0 
TokenList size => 1 
Increment Token => korrika 
### Increment Token ### 
Token Counter => 1 
TokenList size => 1 
### End ### 
### Close ### 

### Reset ### 
### Increment Token ### 
Token Counter => 0 
TokenList size => 1 
Increment Token => korrika 
### Increment Token ### 
Token Counter => 1 
TokenList size => 1 
### End ### 
### Close ### 

Во втором случае он не создает токенизатор, похоже, что он его перезагружает, но он читает старый текст.

Я написал владельцу кода, и он ответил мне, чтобы увидеть TrieTokenizer.

ответ

0

Наконец-то я сделал!

Я модифицировал PatternTokenizer, а затем использовал StandardTokenizer для использования lemmatizer. Вкратце, я леммитирую строку из ввода, а затем создаю StringReader с леммматизированным текстом.

Вот код, надеюсь, что это может быть полезным для кого-то (Изменение сценария StandardTokenizer):

...

public String processReader(Reader reader) throws IOException { 
    char[] arr = new char[8 * 1024]; // 8K at a time 
    StringBuffer buf = new StringBuffer(); 
    int numChars; 
    while ((numChars = reader.read(arr, 0, arr.length)) > 0) { 
     buf.append(arr, 0, numChars); 
    } 
    return lemmatizer.getLemma(buf.toString()); 
} 

...

public void reset() throws IOException { 
    scanner.yyreset(new StringReader(processReader(input))); 
} 
0

Уверена, что проблема связана с лематизатором? Вы можете проверить это, поместив текст в экран анализа в пользовательский интерфейс администратора. Введите текст и посмотрите, что делает цепочка анализатора.

Однако следующая часть:

Если я жду немного (или, если я перестану Solr и я бегу его), и я прошу «jolasten» текст я получаю текст хорошо lemmatized

заставляет меня думать, что, может быть, вы просто забыли зафиксировать свой проиндексированный текст. Затем задержка перед отображением содержимого будет объясняться мягким фиксацией с интервалом, настроенным в файле solrconfig.xml.

+0

Спасибо Alexandre, Я ответил, что вы редактируете мой вопрос (комментарий слишком длинный, чтобы ответить вам здесь) – Gotz84

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