Lucene标记文本的过程

use*_*336 3 lucene static-classes

这可以被视为一般的Java问题,但为了更好地理解我使用Lucene作为示例.

您可以在Lucene中使用不同的Tokenizer来标记文本.有主要的抽象Tokenizer类,然后是许多扩展它的不同类.TokenFilter也是如此.

现在,似乎每次要索引文档时,都会创建一个新的Tokenizer.问题是,既然Tokeinzer只是一个实用类,为什么不让它静止?例如,将所有字母转换为小写字母的Tokenizer可以使用静态方法,该方法只对每个输入所做的输入执行.为我们想要索引的每一段文本创建一个新对象有什么意义?

有一点需要提及 - Tokeinzer有一个私有字段,其中包含它接收到的令牌化输入.我只是不明白为什么我们需要以这种方式存储它,因为对象在标记化过程结束后立即被销毁并返回新的标记化文本.我唯一能想到的是多线程访问可能吗?

谢谢!

Rob*_*uir 6

现在,似乎每次要索引文档时,都会创建一个新的Tokenizer

事实并非如此,调用了Analyzer.reusableTokenStream方法,该方法不仅重用了Tokenizer,还重用了整个链(TokenFilters等).请参阅http://lucene.apache.org/java/3_0_0/api/core/org/apache/lucene/analysis/Analyzer.html#reusableTokenStream(java.lang.String,java.io.Reader)

有一点需要提及 - Tokeinzer有一个私有字段,其中包含它接收到的令牌化输入.我只是不明白为什么我们需要以这种方式存储它,因为对象在标记化过程结束后立即被销毁并返回新的标记化文本.我唯一能想到的是多线程访问可能吗?

如前所述,整个Chain of tokenizer和tokenfilters在文档中重用.因此,所有属性都被重用,但重要的是要注意属性在整个链中共享(例如,所有Tokenizer和TokenFilters的属性引用指向相同的实例).这就是为什么在tokenizer中调用clearAttributes()来重置所有属性至关重要.

例如,Whitespace标记器在其ctor中添加对TermAttribute的引用,并由LowerCaseFilter包装,它还在其ctor中添加对TermAttribute的引用.这两个TermAttributes都指向相同的底层char [].处理新文档时,将调用Analyzer.reusableTokenStream,它返回前一文档中使用的相同TokenStream链(在本例中为使用LowerCaseFilter包装的空白).调用reset(Reader)方法,将tokenizer的输入重置为新文档内容.最后在整个流上调用reset(),它会重置前一个文档中的任何内部状态,并处理内容直到incrementToken()返回false.