我试图在Lucene中创建自己的自定义分析器和标记器类。我主要按照这里的说明进行操作:
http://www.citrine.io/blog/2015/2/14/building-a-custom-analyzer-in-lucene
我根据需要进行了更新(在Lucene的新版本中,Reader存储在"输入")
但是我得到一个例外:
TokenStream合同违规:reset()/ close()调用缺失,reset()多次调用,或者子类不调用super.reset()。有关正确的使用工作流程的更多信息,请参阅TokenStream类的Javadocs。
这可能是什么原因?我收集调用reset \ close根本不是我的工作,但应该由分析仪完成。
这是我的自定义分析器类:
public class MyAnalyzer extends Analyzer {
protected TokenStreamComponents createComponents(String FieldName){
// TODO Auto-generated method stub
return new TokenStreamComponents(new MyTokenizer());
}
}
我的自定义分类器类:
public class MyTokenizer extends Tokenizer {
protected CharTermAttribute charTermAttribute =
addAttribute(CharTermAttribute.class);
public MyTokenizer() {
char[] buffer = new char[1024];
int numChars;
StringBuilder stringBuilder = new StringBuilder();
try {
while ((numChars =
this.input.read(buffer, 0, buffer.length)) != -1) {
stringBuilder.append(buffer, 0, numChars);
}
}
catch (IOException e) {
throw new RuntimeException(e);
}
String StringToTokenize = stringBuilder.toString();
Terms=Tokenize(StringToTokenize);
}
public boolean incrementToken() throws IOException {
if(CurrentTerm>=Terms.length)
return false;
this.charTermAttribute.setEmpty();
this.charTermAttribute.append(Terms[CurrentTerm]);
CurrentTerm++;
return true;
}
static String[] Tokenize(String StringToTokenize){
//Here I process the string and create an array of terms.
//I tested this method and it works ok
//In case it's relevant, I parse the string into terms in the //constructor. Then in IncrementToken I simply iterate over the Terms array and //submit them each at a time.
return Processed;
}
public void reset() throws IOException {
super.reset();
Terms=null;
CurrentTerm=0;
};
String[] Terms;
int CurrentTerm;
}
当我跟踪Exception时,我发现问题出在input.read上 - 似乎输入内部没有任何内容(或者其中有一个ILLEGAL_STATE_READER)我不明白它。
答案 0 :(得分:2)
在重置之前,您正在读取Tokenizer构造函数中的输入流。
我认为,问题在于您将输入作为String处理,而不是作为Stream处理。目的是让您有效地从incrementToken
方法中读取流,而不是将整个流加载到字符串中并预处理大字符串。开头的令牌列表。
但是可以走这条路。只需将构造函数中当前的所有逻辑移到reset
方法中(在super.reset()
调用之后)。