lucene 研究
- 格式:doc
- 大小:103.00 KB
- 文档页数:14
lucene 的分析器(analyzer)与分词器(tokenizer)和过滤器(tokenfilter)关键字: lucene analyzer tokenizer tokenfilter 豆子小说作者:1987(lianj_lee)好久没有写博客了,最近确实是有点忙。
这几天在给IK做测试,很高兴,我能为IK做贡献,希望以后能继续。
正是由于给做测试工作,所以我就把关于lucene的分析器,过滤器和分词器这些东西温习了下,然后希望这个博客能给大家带来一定帮助。
还有我想从今天声明一下,欢迎大家转载我的博客,我希望给越来越多的人带来帮助,但是请务必注明作者, 1987(lianj_lee)入正题:1〉analyzer主要包含分词器跟过滤器,他的功能就是:将分词器跟分析器进行合理的组合,使之产生对文本分词和过滤效果。
因此,分析器使用分词和过滤器构成一个管道,文本在“滤过”这个管道之后,就成为可以进入索引的最小单位。
2〉tokenizer主要用于对文本资源进行切分,将文本规则切分为一个个可以进入索引的最小单元3〉tokenfilter主要对分词器切分的最小单位进入索引进行预处理,如:大写转小写,复数转单数,也可以复杂(根据语义改写拼写错误的单词)附上lucene的部分类源码以讲解:public abstract TokenStream tokenStream(String fieldName, Reader reader);//该抽象为子分析器扩展,后面会在说到public TokenStream reusableTokenStream(String fieldName, Reader reader) throws IOException {return tokenStream(fieldName, reader);}//这个是后来发行版本添加的,主要用途是:创建一个TokenStream,为了同一个线程重复使用,节省时间private CloseableThreadLocal tokenStreams = new CloseableThreadLocal();// 利用ThreadLocal 来达到在同一个线程重复使用。
这种应用很普遍,例如hibernate的session也是这种情况protected Object getPreviousTokenStream() {try {return tokenStreams.get();} catch (NullPointerException npe) {if (tokenStreams == null) {throw new AlreadyClosedException("this Analyzer is closed");} else {throw npe;}}}protected void setPreviousTokenStream(Object obj) {try {tokenStreams.set(obj);} catch (NullPointerException npe) {if (tokenStreams == null) {throw new AlreadyClosedException("this Analyzer is closed");} else {throw npe;}}}public int getPositionIncrementGap(String fieldName){return 0;}public void close() {tokenStreams.close();tokenStreams = null;}public TokenStream tokenStream(String fieldName, Reader reader) {StandardTokenizer tokenStream = new StandardTokenizer(reader, replaceInvalidAcronym);tokenStream.setMaxTokenLength(maxTokenLength);TokenStream result = new StandardFilter(tokenStream);result = new LowerCaseFilter(result);result = new StopFilter(result, stopSet);return result;}StandardAnalyzer提供的实现,可以看到很简单,就是组合了分词跟过滤器,首先实例了StandardTokenizer(),然后获得了tokenStream,将他传入过滤器,在这样的过程中,result 没有发生任何改变,真正发生改变的是在建立索引或者搜索的时候,继续往下看,public StandardTokenizer(Reader input, boolean replaceInvalidAcronym) {this.replaceInvalidAcronym = replaceInvalidAcronym;this.input = input;this.scanner = new StandardTokenizerImpl(input);}StandardTokenizerImpl的构造方法:StandardTokenizerImpl(java.io.Reader in) {this.zzReader = in;}StartdFilter的构造方法:public StandardFilter(TokenStream in) {super(in);}当建立索引或者搜索的时候,会调用由tokenStream方法返回的TokenStream的next()方法,也是这个时候真正的分词和过滤就开始了。
接着看,当第一调用next()方法时候,首先应该进入StopFilter的next,因为result = new StopFilter(result, stopSet);public final Token next(final Token reusableToken) throws IOException {assert reusableToken != null;// return the first non-stop word foundint skippedPositions = 0;for (Token nextToken = input.next(reusableToken); nextToken != null; nextToken = input.next(reusableToken)) {if (!stopWords.contains(nextToken.termBuffer(), 0, nextToken.termLength())) { if (enablePositionIncrements) {nextToken.setPositionIncrement(nextToken.getPositionIncrement() + skippedPositions);}return nextToken;}skippedPositions += nextToken.getPositionIncrement();}// reached EOS -- return nullreturn null;}在这里是调用input的next(),这个input是在初始化stopFilter时进行的,其实input初始化操作也就是也就是把以参数方式传入的result给input,这个result是流经上层的过滤器过来的,回过来看看吧StandardTokenizer tokenStream = new StandardTokenizer(reader, replaceInvalidAcronym);tokenStream.setMaxTokenLength(maxTokenLength);TokenStream result = new StandardFilter(tokenStream);result = new LowerCaseFilter(result);result = new StopFilter(result, stopSet);是LowerCaseFilter, 其实在LowerCaseFilter中,也是按照同样的道理,这样由底层往上层追溯,然后再向下层流,这也是lucene的架构经典之处。
还有在分词器这里,使用的是JAVACC生成的分词器,他的优越性在于简单性和可扩展性。
lucene文件格式关键字: lucene index file 文件格式 豆子小说网转自:/wiki/2007/255.html索引文件格式本文定义了Lucene(版本1.3)用到的索引文件的格式。
Jakarta Lucene是用Java写成的,同时有很多团体正在默默的用其他的程序语言来改写它。
如果这些新的版本想和Jakarta Lucene兼容,就需要一个与具体语言无关的Lucene索引文件格式。
本文正是试图提供一个完整的与语言无关的Jakarta Lucene 1.3索引文件格式的规格定义。
随着Lucene不断发展,本文也应该更新。
不同语言写成的Lucene实现版本应当尽力遵守文件格式,也必须产生本文的新版本。
本文同时提供兼容性批注,描述文件格式上与前一版本不同的地方。
定义Lucene中最基础的概念是索引(index),文档(document),域(field)和项(term)。
索引包含了一个文档的序列。
· 文档是一些域的序列。
· 域是一些项的序列。
· 项就是一个字串。
存在于不同域中的同一个字串被认为是不同的项。
因此项实际是用一对字串表示的,第一个字串是域名,第二个是域中的字串。
倒排索引为了使得基于项的搜索更有效率,索引中项是静态存储的。
Lucene的索引属于索引方式中的倒排索引,因为对于一个项这种索引可以列出包含它的文档。
这刚好是文档与项自然联系的倒置。
域的类型Lucene中,域的文本可能以逐字的非倒排的方式存储在索引中。
而倒排过的域称为被索引过了。
域也可能同时被存储和被索引。
域的文本可能被分解许多项目而被索引,或者就被用作一个项目而被索引。
大多数的域是被分解过的,但是有些时候某些标识符域被当做一个项目索引是很有用的。
段(Segment)Lucene索引可能由多个子索引组成,这些子索引成为段。
每一段都是完整独立的索引,能被搜索。