- 浏览: 412690 次
- 性别:
- 来自: 北京
最新评论
-
springdata_spring:
apache lucene开源框架demo使用实例教程源代码下 ...
有关Lucene的问题(6):Lucene的事务性 -
jaychang:
必须要感谢作者的分享,对理解Lucene的工作原理帮助很大
Lucene学习总结之一:全文检索的基本原理 -
yin_kaihua:
...
Lucene学习总结之三:Lucene的索引文件格式 (1) -
djh122:
...
Lucene 原理与代码分析完整版 -
wayne0830:
多谢楼主分享!
Lucene 原理与代码分析完整版
5、DocumentsWriter对CharBlockPool,ByteBlockPool,IntBlockPool的缓存管理
- 在索引的过程中,DocumentsWriter将词信息(term)存储在CharBlockPool中,将文档号(doc ID),词频(freq)和位置(prox)信息存储在ByteBlockPool中。
- 在ByteBlockPool中,缓存是分块(slice)分配的,块(slice)是分层次的,层次越高,此层的块越大,每一层的块大小事相同的。
- nextLevelArray表示的是当前层的下一层是第几层,可见第9层的下一层还是第9层,也就是说最高有9层。
- levelSizeArray表示每一层的块大小,第一层是5个byte,第二层是14个byte以此类推。
ByteBlockPool类中有以下静态变量: final static int[] nextLevelArray = {1, 2, 3, 4, 5, 6, 7, 8, 9, 9}; |
- 在ByteBlockPool中分配一个块的代码如下:
//此函数仅仅在upto已经是当前块的结尾的时候方才调用来分配新块。 public int allocSlice(final byte[] slice, final int upto) { //可根据块的结束符来得到块所在的层次。从而我们可以推断,每个层次的块都有不同的结束符,第1层为16,第2层位17,第3层18,依次类推。 final int level = slice[upto] & 15; //从数组总得到下一个层次及下一层块的大小。 final int newLevel = nextLevelArray[level]; final int newSize = levelSizeArray[newLevel]; // 如果当前缓存总量不够大,则从DocumentsWriter的freeByteBlocks中分配。 if (byteUpto > DocumentsWriter.BYTE_BLOCK_SIZE-newSize) nextBuffer(); final int newUpto = byteUpto; final int offset = newUpto + byteOffset; byteUpto += newSize; //当分配了新的块的时候,需要有一个指针从本块指向下一个块,使得读取此信息的时候,能够在此块读取结束后,到下一个块继续读取。 //这个指针需要4个byte,在本块中,除了结束符所占用的一个byte之外,之前的三个byte的数据都应该移到新的块中,从而四个byte连起来形成一个指针。 buffer[newUpto] = slice[upto-3]; buffer[newUpto+1] = slice[upto-2]; buffer[newUpto+2] = slice[upto-1]; // 将偏移量(也即指针)写入到连同结束符在内的四个byte slice[upto-3] = (byte) (offset >>> 24); slice[upto-2] = (byte) (offset >>> 16); slice[upto-1] = (byte) (offset >>> 8); slice[upto] = (byte) offset; // 在新的块的结尾写入新的结束符,结束符和层次的关系就是(endbyte = 16 | level) buffer[byteUpto-1] = (byte) (16|newLevel); return newUpto+3; } |
- 在ByteBlockPool中,文档号和词频(freq)信息是应用或然跟随原则写到一个块中去的,而位置信息(prox)是写入到另一个块中去的,对于同一个词,这两块的偏移量保存在IntBlockPool中。因而在IntBlockPool中,每一个词都有两个int,第0个表示docid + freq在ByteBlockPool中的偏移量,第1个表示prox在ByteBlockPool中的偏移量。
- 在写入docid + freq信息的时候,调用termsHashPerField.writeVInt(0, p.lastDocCode),第一个参数表示向此词的第0个偏移量写入;在写入prox信息的时候,调用termsHashPerField.writeVInt(1, (proxCode<<1)|1),第一个参数表示向此词的第1个偏移量写入。
- CharBlockPool是按照出现的先后顺序保存词(term)
- 在TermsHashPerField中,有一个成员变量RawPostingList[] postingsHash,为每一个term分配了一个RawPostingList,将上述三个缓存关联起来。
abstract class RawPostingList { final static int BYTES_SIZE = DocumentsWriter.OBJECT_HEADER_BYTES + 3*DocumentsWriter.INT_NUM_BYTE; int textStart; //此词在CharBlockPool中的偏移量,由此可以知道是哪个词。 int intStart; //此词在IntBlockPool中的偏移量,在指向的位置有两个int,一个是docid + freq信息的偏移量,一个是prox信息的偏移量。 int byteStart; //此词在ByteBlockPool中的起始偏移量 } static final class PostingList extends RawPostingList { int docFreq; // 此词在此文档中出现的次数 int lastDocID; // 上次处理完的包含此词的文档号。 int lastDocCode; // 文档号和词频按照或然跟随原则形成的编码 int lastPosition; // 上次处理完的此词的位置 } 这里需要说明的是,在IntBlockPool中保存了两个在ByteBlockPool中的偏移量,而在RawPostingList的byteStart又保存了在ByteBlockPool中的偏移量,这两者有什么区别呢? 在IntBlockPool中保存的分别指向docid+freq及prox信息在ByteBlockPool中的偏移量是主要用来写入信息的,它记录的偏移量是下一个要写入的docid+freq或者prox在ByteBlockPool中的位置,随着信息的不断写入,IntBlockPool中的两个偏移量是不断改变的,始终指向下一个可以写入的位置。 RawPostingList中byteStart主要是用来读取docid及prox信息的,当索引过程基本结束,所有的信息都写入在缓存中了,那么如何找到此词对应的文档号偏移量及位置信息,然后写到索引文件中去呢?自然是通过RawPostingList找到byteStart,然后根据byteStart在ByteBlockPool中找到docid+freq及prox信息的起始位置,从起始位置开始的两个大小为5的块,第一个就是docid+freq信息的源头,第二个就是prox信息的源头,如果源头的块中包含了所有的信息,读出来就可以了,如果源头的块中有指针,则沿着指针寻找到下一个块,从而可以找到所有的信息。 |
- 下面举一个实例来表明如果进行缓存管理的:
此例子中,准备添加三个文件: file01: common common common common common term file02: common common common common common term term file03: term term term common common common common common file04: term (1) 添加第一篇文档第一个common
(2) 添加第四个common
(3) 添加第五个common
(4) 添加第一篇文档,第一个term
(5) 添加第二篇文档第一个common
(6) 添加第二篇文档第一个term
(7) 添加第三篇文档的第一个term
(8) 添加第三篇文档第二个term
(9) 添加第三篇文档第四个common
(10) 添加第三篇文档的第五个common
(11) 添加第四篇文档的第一个term
(12) 最终PostingList, CharBlockPool, IntBlockPool,ByteBlockPool的关系如下图:
|
评论
其实 在前几篇 我已经开始力不从心了...
发表评论
-
Lucene应用开发揭秘
2011-09-25 22:13 5354Lucene应用开发揭秘 ... -
Lucene应用开发揭秘上线了
2011-09-09 23:54 114Lucene应用开发揭秘 华章培训网地址:http:/ ... -
LinkedIn公司实现的实时搜索引擎Zoie
2010-11-29 21:19 8488一、总体架构 Zoie是linkedin公司基于Luce ... -
Lucene 原理与代码分析完整版
2010-06-13 01:30 34952Lucene 原理与代码分析系列文章已经基本告一段落, ... -
Lucene学习总结之十:Lucene的分词器Analyzer
2010-06-06 22:13 71401、抽象类Analyzer 其主要包含两个接口,用于生 ... -
Lucene学习总结之九:Lucene的查询对象
2010-05-19 02:39 2800Lucene学习总结之九:Lucene的查询对象(1) ... -
Lucene学习总结之九:Lucene的查询对象(3)
2010-05-19 02:37 29636、FilteredQuery FilteredQu ... -
Lucene学习总结之九:Lucene的查询对象(2)
2010-05-19 02:36 26035、SpanQuery 所谓SpanQ ... -
Lucene学习总结之九:Lucene的查询对象(1)
2010-05-19 02:34 6326Lucene除了支持查询语法以外,还可以自己构造查询对象 ... -
Lucene学习总结之八:Lucene的查询语法,JavaCC及QueryParser
2010-05-08 13:41 2388Lucene学习总结之八:Lucene的查询语法,Java ... -
Lucene学习总结之八:Lucene的查询语法,JavaCC及QueryParser(2)
2010-05-08 00:25 5539三、解析QueryParser.jj 3.1、声明Qu ... -
Lucene学习总结之八:Lucene的查询语法,JavaCC及QueryParser(1)
2010-05-08 00:20 8379一、Lucene的查询语法 Lucene所支持的查询语 ... -
Lucene学习总结之七:Lucene搜索过程解析
2010-04-05 14:52 2950本系列文章将详细描述几乎最新版本的Lucene的基本原理 ... -
Lucene学习总结之七:Lucene搜索过程解析
2010-04-04 22:54 2642本系列文章将详细描述几乎最新版本的Lucene的基本原理 ... -
Lucene学习总结之七:Lucene搜索过程解析(8)
2010-04-04 22:43 76562.4、搜索查询对象 2.4.4、收集文档结果集 ... -
Lucene学习总结之七:Lucene搜索过程解析(7)
2010-04-04 22:39 43612.4、搜索查询对象 2.4.3.2、并集Di ... -
Lucene学习总结之七:Lucene搜索过程解析(6)
2010-04-04 22:20 36172.4、搜索查询对象 2.4.3、进行倒排表合并 在 ... -
Lucene学习总结之七:Lucene搜索过程解析(5)
2010-04-04 21:26 43262.4、搜索查询对象 2.4.2、创建Score ... -
Lucene学习总结之七:Lucene搜索过程解析(4)
2010-04-04 20:46 44492.4、搜索查询对象 2.4.1.2、创建Weight ... -
Lucene学习总结之七:Lucene搜索过程解析(3)
2010-04-04 20:19 42992.3、QueryParser解析查询语句生成查询对象 代码 ...
相关推荐
Lucene学习总结之一:全文检索的基本原理 Lucene学习总结之二:Lucene的总体架构 ...Lucene学习总结之四:Lucene索引过程分析(3) Lucene学习总结之四:Lucene索引过程分析(4) www.chinaandroid.com
本系列文章将详细描述几乎最新版本的Lucene的基本...Lucene学习总结之四:Lucene索引过程分析(3) http://www.cnblogs.com/forfuture1978/archive/2010/02/02/1661441.html Lucene学习总结之四:Lucene索引过程分析(4) ...
1.8 Lucene学习总结之四:Lucene索引过程分析(3) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .116 1.9 Lucene学习总结之四:Lucene索引过程分析(4) . . . . . . . . . . . . ....
Lucene之删除索引 Lucene之删除索引 Lucene之删除索引 http://blog.csdn.net/nupt123456789/article/details/10666105
lucene学习总结:lucene全文检索的原理,索引文件的格式,lucene的整体架构
Lucene的基础知识 ...6、分析器的分析过程 a) 测试分析器的分词效果 b) 第三方中文分析器 7、索引库的维护 a) 添加文档 b) 删除文档 c) 修改文档 Lucene的高级查询、solr入门 solr在项目中的应用及电商搜索实现
Lucene索引器实例Lucene索引器实例Lucene索引器实例Lucene索引器实例
基于lucene技术的增量索引,实现索引的首次创建,动态增删改
lucene 对 xml建立索引 建立索引就是怎么简单 呵呵
NULL 博文链接:https://iamyida.iteye.com/blog/2199848
Lucene创建索引,查询索引的简单使用。
3:删除索引 4:检查索引文件 5:恢复删除的索引 6:强制删除 7:更新索引 8:合并索引 9:高亮回显 供大家参考学习 public static void main(String[] args) { LuceneUtil luceneUtil = new LuceneUtil(); // ...
Lucene创建索引步骤: 1、创建Directory(索引位置) 2、创建IndexWrite(写入索引) 3、创建Document对象 4、为Document添加Field(相当于添加属性:类似于表与字段的关系) 5、通过IndexWriter添加文档到索引中
lucene 索引 查看 工具
lucene索引查看工具及源码lucene索引查看工具及源码lucene索引查看工具及源码
赠送jar包:lucene-core-7.2.1.jar; 赠送原API文档:lucene-core-7.2.1-javadoc.jar; 赠送源代码:lucene-core-7.2.1-sources.jar; 赠送Maven依赖信息文件:lucene-core-7.2.1.pom; 包含翻译后的API文档:lucene...
Lucene3.0创建索引 读取目录下的所有txt文档格式的文件,然后生成一个索引文件到某目录下!
lucene索引结构原理
这款已经老了,2.4以后的lucene索引用不了。我上传了最新版本的,有需要的话!请到http://download.csdn.net/source/1423241 下。一款可以查看Lucene分词后在索引的排名以及是否有无该词,很多时候用于查看有无需要...
深入 Lucene 索引机制深入 Lucene 索引机制深入 Lucene 索引机制深入 Lucene 索引机制深入 Lucene 索引机制深入 Lucene 索引机制