【发布时间】:2016-03-10 14:06:01
【问题描述】:
我正在使用Lucene 开发一个索引器,上周在代码中添加了存储TermVectors 以便我可以尝试反馈和其他有趣的东西。在存储术语向量的这一步之后,我开始收到以下错误:
java.lang.IllegalArgumentException: 文档包含至少一个 field="f_common.document.text" 中的巨大术语(其 UTF8 编码 比最大长度 32766 长),所有这些都被跳过了。 请更正分析器以不产生此类术语。前缀 第一个巨大的术语是:'[34, 60, 97, 99, 114, 101, 58, 98, 108、111、99、107、62、32、32、32、60、100、105、118、32、97、99、 114, 101, 58, 100, 101, 102, 61]...',原消息:字节可以 长度最多为 32766;得到 34444
好的,没问题。 (嗯,死在一个过长的令牌上对我来说感觉像是一个错误,但这是在 4.8 中有意识的 API 移动。)所以我添加了以下 AnalyzerWrapper 来解决这个问题:
import java.io.IOException;
import java.io.StringReader;
import java.util.HashSet;
import java.util.Set;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.AnalyzerWrapper;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.miscellaneous.LengthFilter;
import org.apache.lucene.index.IndexWriter;
/*
* Lucene's IndexWriter.addDocument() will pitch an exception if the document contains a token that is too long.
* I would rather just drop long tokens.
*/
public class SafetyAnalyzer extends AnalyzerWrapper {
private Analyzer baseAnalyzer;
public SafetyAnalyzer(Analyzer baseAnalyzer) {
super(Analyzer.PER_FIELD_REUSE_STRATEGY);
this.baseAnalyzer = baseAnalyzer;
}
@Override
public void close() {
baseAnalyzer.close();
super.close();
}
@Override
protected Analyzer getWrappedAnalyzer(String fieldName) {
return baseAnalyzer;
}
@Override
protected TokenStreamComponents wrapComponents(String fieldName, TokenStreamComponents components) {
TokenStream ts = components.getTokenStream();
LengthFilter drop_long_tokens = new LengthFilter(ts, 0, IndexWriter.MAX_TERM_LENGTH);
return new TokenStreamComponents(components.getTokenizer(), drop_long_tokens);
}
}
这应该会丢弃IndexWriter 会吐出的长标记。这像这样包装其他分析器:
public Analyzer getDefaultIndexAnalyzer() throws Exception {
if (defaultIndexAnalyzer == null) {
String defaultAnalyzerName = getConfig("LUCENE_INDEX_ANALYZER_DEFAULT");
if (defaultAnalyzerName == null)
defaultAnalyzerName = "org.apache.lucene.analysis.standard.StandardAnalyzer";
defaultIndexAnalyzer = new SafetyAnalyzer((Analyzer)Class.forName(defaultAnalyzerName).newInstance());
}
return defaultIndexAnalyzer;
}
只是,它不起作用。我仍然在这些令牌上获得 IllegalArgumentExceptions。我能找到的唯一解决方案是在 writer.addDocument() 上抓住 IAE。
我是不是写错了分析器?
【问题讨论】: