Я добавляю текстовый лемматизер в 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.
Спасибо Alexandre, Я ответил, что вы редактируете мой вопрос (комментарий слишком длинный, чтобы ответить вам здесь) – Gotz84