Lucene能不能读取结巴分词词典词典的编号

Lucene检索数据库支持中文检索_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
Lucene检索数据库支持中文检索
上传于|0|0|文档简介
&&Lucene检索数据库支持中文检索
阅读已结束,如果下载本文需要使用0下载券
想免费下载更多文档?
定制HR最喜欢的简历
下载文档到电脑,查找使用更方便
还剩8页未读,继续阅读
定制HR最喜欢的简历
你可能喜欢lucene(24)
反向信息是索引文件的核心,也即反向索引。&
反向索引包括两部分,左面是词典(Term Dictionary),右面是倒排表(Posting List)。&
在 Lucene 中,这两部分是分文件存储的,词典是存储在 tii,tis中的,倒排表又包括两部分,
一部分是文档号及词频,保存在 frq中,一部分是词的位置信息,保存在 prx中。&
 &Term Dictionary (tii, tis) &
 &Frequencies (.frq) &
 &Positions (.prx) &
词典(tis)及词典索引(tii)信息格式如下:
在词典中,所有的词是按照字典顺序排序的。&
1. &词典文件(tis) &
 &1)TermCount:词典中包含的总的词数 &
 &2)IndexInterval:为了加快对词的查找速度,也应用类似跳跃表的结构,假设IndexInterval 为 4,则在词典索引(tii)文件中保存第 4 个,第 8 个,第 12 个词,这
样可以加快在词典文件中查找词的速度。
3)SkipInterval:倒排表无论是文档号及词频,还是位置信息,都是以跳跃表的结构存
在的,SkipInterval是跳跃的步数。 &
4)MaxSkipLevels:跳跃表是多层的,这个值指的是跳跃表的最大层数。 &
5)TermCount个项的数组,每一项代表一个词,对于每一个词,以前缀后缀规则存放词的文本信息(PrefixLength + Suffix),词属于的域的域号(FieldNum),有多少篇文档
包含此词(DocFreq),此词的倒排表在 frq,prx中的偏移量(FreqDelta, ProxDelta),此词的倒排表的跳跃表在 frq 中的偏移量(SkipDelta),这里之所以用 Delta,是应用差
值规则。 &
 2.词典索引文件(tii) &
 1) 词典索引文件是为了加快对词典文件中词的查找速度,保存每隔 IndexInterval 个词。 &
 &2)词典索引文件是会被全部加载到内存中去的。 &
 &3)IndexTermCount = TermCount / IndexInterval:词典索引文件中包含的词数。 &
 &4)IndexInterval同词典文件中的 IndexInterval。 &
 &5)SkipInterval同词典文件中的 SkipInterval。 &
 &6)MaxSkipLevels同词典文件中的 MaxSkipLevels。 &
 &7)IndexTermCount个项的数组,每一项代表一个词,每一项包括两部分,第一部分是词本身(TermInfo),第二部分是在词典文件中的偏移量(IndexDelta)。假设IndexInterval为4,此数组中保存第4 个,第8个,第 12个词。
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:655505次
积分:5532
积分:5532
排名:第9559名
原创:30篇
转载:198篇
评论:60条
(5)(2)(10)(25)(17)(1)(10)(1)(1)(2)(2)(4)(7)(18)(4)(1)(8)(17)(5)(3)(15)(5)(3)(8)(2)(4)(4)(1)(6)(13)(22)(7)(2)Lucene4学习笔记之索引文件介绍与数据类型 -
- ITeye技术网站
博客分类:
Lucene生成的索引文件
由上文中提到的代码生成的索引文件如下所示:
格式都相当怪异,那些这些文件里面都存放了些什么东西?我们先来了解如下名词
a)段信息(SegmentInfo):它包含段的元数据;
b)字段名(Field name):它包含了用来构建索引的字段名;
c)存储的字段值(Stored Field values):它包含每一个文档的属性-值(attribute-value)对的列表,其中属性名为字段的名称,用来存储和文档相关的辅助信息。比如标题,网址或者是一个用来访问数据库的标识符,在进行搜索时用来作为key来取得返回值;
d)词典(Term Dictionary):包含所有文档的所有索引字段中使用的词,也包含一个词在文档中的数量,和词的频率数据、接近度数据的指针;
e)词的频率数据(Term Frequency Data):对词典里面的每个词而言,都有其在所有文档中包含数量以及在某一个文档中的数量,如果频率这个属性被省略掉就不会出现;
f)词的接近度数据(Term Proximity Data):在词典中的每个词在每一个文档中的位置数据,如果位置属性被省略了就不会出现;
g)标准化系数(Normalization Factors):对文档中的每个字段,存储了一个值为该字段的命中值Lucene在计算每个词的权重的时候都会乘上该标准化系数;
h)词向量(Term Vectors):对文档中的每一个字段,词向量都可能被存储,一个词向量由词文本以及词的频率组成;
i) 每个文档的值(Per-Document Values):但一般都被加载到内存中用于快速访问,虽然存储的值通常用于作为搜索结果的摘要,但每一个文档的值都是非常有用的,比如在计算评分的时候作为评分系数;
j) 删除的文档(Deleted Documents):用来指示哪些文档被删除的文件
段文件(Segments File)
segments.gen
segments_N
存储提交点信息
锁文件(Lock File)
write.lock
用来阻止多个indexWriter向同一个文件写数据
段信息(Segments Info)
存储段的元数据信息
复合文件(Compound File)
.cfs , .cfe
一个可选的虚拟文件,包括所有其他索引文件系统频繁用完的文件句柄
字段信息(Fields)
存储字段的信息
字段索引(Fields Index)
包含指向字段值的指针
字段数据(Field Data)
存储文档里面的字段信息
词典(Term Dictionary)
存储词信息
词索引(Term Index)
指向词典的索引
频率信息(Frequencies)
包含那些含有每一个词的频率的文档列表
位置信息(Positions)
存储词在索引中出现的位置信息
额外存储每个位置的元数据信息,如字符偏移和用户负载
.nvd , .nvm
文档和字段的length和boost系数的编码
每个文档的值(Per-Document Values)
.dvd , .dvm
额外的得分系数或者每个文档的值信息编码
词向量索引(Term Vector Index)
存储文档的偏移数据文件
词向量文件(Term Vector Documents)
包含有词向量的文档信息
词向量字段(Term Vector Fields)
关于词向量的字段级信息
删除文档(Deleted Documents)
关于什么文件被删除的信息
数据存储基本类型
16 bit 二字节无符号整型,高位优先(short)
32 bit四字节无符号整型,高位优先(int)
64 bit八字节无符号整型,高位优先(long)
可变长度整型。0-127单字节,128-16383两字节,类推
可变长度Long型
UNICODE字符串
写入格式为:VInt,Chars,字符串长度加字符串值
前面4种类型我们可以将其称为简单类型,因为它们的存储单元均为字节Byte,并遵守高位字节先输出,低位字节后输出的原则。下面以Int32类型为例,看一下它在lucene4中的读写情况:
public void writeInt(int i) throws IOException {
writeByte((byte)(i && 24));//先写入高八位
writeByte((byte)(i && 16));
writeByte((byte)(i &&
writeByte((byte) i);//最后写入低八位
public int readInt() throws IOException {
//先输出高位;后输出低位
return ((readByte() & 0xFF) && 24) | ((readByte() & 0xFF) && 16)
| ((readByte() & 0xFF) &&
(readByte() & 0xFF);
VInt类型可能比较难理解,我们来深入看一下:
·变长的整数类型,它可能包含多个Byte,对于每个Byte的8位,其中后7位表示数值,最高1位表示是否还有另一个Byte,0表示没有,1表示有。
·越前面的Byte表示数值的低位,越后面的Byte表示数值的高位。
·例如130化为二进制为 ,总共需要8位,一个Byte表示不了,因而需要两个Byte来表示,第一个Byte表示后7位,并且在最高位置1来表示后面还有一个Byte,所以为(1) 0000010,第二个Byte表示第8位,并且最高位置0来表示后面没有其他的Byte了,所以为(0) 0000001
第一个Byte
第二个Byte
第三个Byte
我们看一下它具体的读写代码:
public final void writeVInt(int i) throws IOException {
//后七位之前还有为1的位存在
while ((i & ~0x7F) != 0) {
//先取出低七位 ,并在第八位补1,指示后面还存在byte
writeByte((byte)((i & 0x7F) | 0x80));
//写入余下的八位
writeByte((byte)i);
public int readVInt() throws IOException {
//读取第一个byte
byte b = readByte();
//大于0即最高位为0,没有下一个byte,直接返回
if (b &= 0)
//获取低七位的值
int i = b & 0x7F;
//读下一个byte
b = readByte();
//获取低七位的值并左移七位与之前的七位数据相加
i |= (b & 0x7F) && 7;
if (b &= 0)
b = readByte();
i |= (b & 0x7F) && 14;
if (b &= 0)
b = readByte();
i |= (b & 0x7F) && 21;
if (b &= 0)
b = readByte();
i |= (b & 0x0F) && 28;
if ((b & 0xF0) == 0)
throw new IOException("Invalid vInt detected (too many bits)");
VLong的相关读写实现与之类似,只是字节数不一样,这里不再重复介绍。最后看一下String相关:
public void writeString(String s) throws IOException {
final BytesRef utf8Result = new BytesRef(10);
UnicodeUtil.UTF16toUTF8(s, 0, s.length(), utf8Result);
//写入字符串长度
writeVInt(utf8Result.length);
//写入字符串值
writeBytes(utf8Result.bytes, 0, utf8Result.length);
public String readString() throws IOException {
//读取字符串长度
int length = readVInt();
final byte[] bytes = new byte[length];
//读取一个字符串长度的byte
readBytes(bytes, 0, length);
return new String(bytes, 0, length, IOUtils.CHARSET_UTF_8);
xiaodongdong
浏览: 56996 次
来自: 长沙
lku1314 写道您好!
看了你的博客解决我在安装spar ...
看了你的博客解决我在安装spark期间 发生的错误同 ...
参考了一下openfire源码项目的启动参数增加到VM环境参数 ...
foreverandever 写道xiaodongdong 写 ...
怎么找不到window文件夹啊?Lucene是一个高性能的java全文检索工具包,它使用的是倒排文件索引结构。该结构及相应的生成算法如下:    0)设有两篇文章1和2  文章1的内容为:Tom lives in Guangzhou,I live in Guangzhou too.  文章2的内容为:He once lived in Shanghai.    1)由于lucene是基于关键词索引和查询的,首先我们要取得这两篇文章的关键词,通常我们需要如下处理措施  a.我们现在有的是文章内容,即一个字符串,我们先要找出字符串中的所有单词,即分词。英文单词由于用空格分隔,比较好处理。中文单词间是连在一起的需要特殊的分词处理。  b.文章中的”in”, “once” “too”等词没有什么实际意义,中文中的“的”“是”等字通常也无具体含义,这些不代表概念的词可以过滤掉  c.用户通常希望查“He”时能把含“he”,“HE”的文章也找出来,所以所有单词需要统一大小写。  d.用户通常希望查“live”时能把含“lives”,“lived”的文章也找出来,所以需要把“lives”,“lived”还原成“live”  e.文章中的标点符号通常不表示某种概念,也可以过滤掉  在lucene中以上措施由Analyzer类完成    经过上面处理后   文章1的所有关键词为:[tom] [live] [guangzhou] [live] [guangzhou]   文章2的所有关键词为:[he] [live] [shanghai]    2) 有了关键词后,我们就可以建立倒排索引了。上面的对应关系是:“文章号”对“文章中所有关键词”。倒排索引把这个关系倒过来,变成:“关键词”对“拥有该关键词的所有文章号”。文章1,2经过倒排后变成  关键词&&&&&&&&&&&&&& 文章号  guangzhou&&&&&&&& 1  he&&&&&&&&&&&&&&&&&&&& 2  i&&&&&&&&&&&&&&&&&&&&&&& 1  live&&&&&&&&&&&&&&&&&&& 1,2  shanghai&&&&&&&&&&& 2  tom&&&&&&&&&&&&&&&&&& 1    通常仅知道关键词在哪些文章中出现还不够,我们还需要知道关键词在文章中出现次数和出现的位置,通常有两种位置:a)字符位置,即记录该词是文章中第几个字符(优点是关键词亮显时定位快);b)关键词位置,即记录该词是文章中第几个关键词(优点是节约索引空间、词组(phase)查询快),lucene 中记录的就是这种位置。    加上“出现频率”和“出现位置”信息后,我们的索引结构变为:  关键词&&&&&&&&&&&& 文章号[出现频率]&&&&&&&&&&&&&&&&&&&& 出现位置  guangzhou&&&&&&& 1[2]&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 3,6  he&&&&&&&&&&&&&&&&&&&& 2[1]&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 1  i&&&&&&&&&&&&&&&&&&&&&&& 1[1]&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 4  live&&&&&&&&&&&&&&&&&&& 1[2],2[1]&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 2,5,2  shanghai&&&&&&&&&&& 2[1]&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 3  tom&&&&&&&&&&&&&&&&&& 1[1]&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 1    以live 这行为例我们说明一下该结构:live在文章1中出现了2次,文章2中出现了一次,它的出现位置为&#,2”这表示什么呢?我们需要结合文章号和出现频率来分析,文章1中出现了2次,那么&#”就表示live在文章1中出现的两个位置,文章2中出现了一次,剩下的就表示live是文章2中第 2个关键字。    以上就是lucene索引结构中最核心的部分。我们注意到关键字是按字符顺序排列的(lucene没有使用B树结构),因此lucene可以用二元搜索算法快速定位关键词。    实现时 lucene将上面三列分别作为词典文件(Term Dictionary)、频率文件(frequencies)、位置文件 (positions)保存。其中词典文件不仅保存有每个关键词,还保留了指向频率文件和位置文件的指针,通过指针可以找到该关键字的频率信息和位置信息。     Lucene中使用了field的概念,用于表达信息所在位置(如标题中,文章中,url中),在建索引中,该field信息也记录在词典文件中,每个关键词都有一个field信息(因为每个关键字一定属于一个或多个field)。    为了减小索引文件的大小,Lucene对索引还使用了压缩技术。首先,对词典文件中的关键词进行了压缩,关键词压缩为&堉?缀长度,后缀&,例如:当前词为“阿拉伯语”,上一个词为“阿拉伯”,那么“阿拉伯语”压缩为&3,语&。其次大量用到的是对数字的压缩,数字只保存与上一个值的差值(这样可以减小数字的长度,进而减少保存该数字需要的字节数)。例如当前文章号是16389(不压缩要用3个字节保存),上一文章号是16382,压缩后保存7(只用一个字节)。     下面我们可以通过对该索引的查询来解释一下为什么要建立索引。  假设要查询单词 “live”,lucene先对词典二元查找、找到该词,通过指向频率文件的指针读出所有文章号,然后返回结果。词典通常非常小,因而,整个过程的时间是毫秒级的。  而用普通的顺序匹配算法,不建索引,而是对所有文章的内容进行字符串匹配,这个过程将会相当缓慢,当文章数目很大时,时间往往是无法忍受的。本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/geekwang/archive//3410187.aspx是一个高性能的java全文检索工具包,它使用的是倒排文件索引结构。该结构及相应的生成算法如下:  现在也是c#的全文检索工具包了,所以都一样的。  0)设有两篇文章1和2  文章1的内容为:Tom lives in Guangzhou,I live in Guangzhou too.  文章2的内容为:He once lived in Shanghai.    1)由于lucene是基于关键词索引和查询的,首先我们要取得这两篇文章的关键词,通常我们需要如下处理措施  a.我们现在有的是文章内容,即一个字符串,我们先要找出字符串中的所有单词,即分词。英文单词由于用空格分隔,比较好处理。中文单词间是连在一起的需要特殊的分词处理。  b.文章中的”in”, “once” “too”等词没有什么实际意义,中文中的“的”“是”等字通常也无具体含义,这些不代表概念的词可以过滤掉  c.用户通常希望查“He”时能把含“he”,“HE”的文章也找出来,所以所有单词需要统一大小写。  d.用户通常希望查“live”时能把含“lives”,“lived”的文章也找出来,所以需要把“lives”,“lived”还原成“live”  e.文章中的标点符号通常不表示某种概念,也可以过滤掉  在lucene中以上措施由Analyzer类完成    经过上面处理后   文章1的所有关键词为:[tom] [live] [guangzhou] [live] [guangzhou]   文章2的所有关键词为:[he] [live] [shanghai]    2) 有了关键词后,我们就可以建立倒排索引了。上面的对应关系是:“文章号”对“文章中所有关键词”。倒排索引把这个关系倒过来,变成:“关键词”对“拥有该关键词的所有文章号”。文章1,2经过倒排后变成  关键词&&&&&&&&&&&&&& 文章号  guangzhou&&&&&&&& 1  he&&&&&&&&&&&&&&&&&&&& 2  i&&&&&&&&&&&&&&&&&&&&&&& 1  live&&&&&&&&&&&&&&&&&&& 1,2  shanghai&&&&&&&&&&& 2  tom&&&&&&&&&&&&&&&&&& 1    通常仅知道关键词在哪些文章中出现还不够,我们还需要知道关键词在文章中出现次数和出现的位置,通常有两种位置:a)字符位置,即记录该词是文章中第几个字符(优点是关键词亮显时定位快);b)关键词位置,即记录该词是文章中第几个关键词(优点是节约索引空间、词组(phase)查询快),lucene 中记录的就是这种位置。    加上“出现频率”和“出现位置”信息后,我们的索引结构变为:  关键词&&&&&&&&&&&& 文章号[出现频率]&&&&&&&&&&&&&&&&&&&& 出现位置  guangzhou&&&&&&& 1[2]&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 3,6  he&&&&&&&&&&&&&&&&&&&& 2[1]&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 1  i&&&&&&&&&&&&&&&&&&&&&&& 1[1]&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 4  live&&&&&&&&&&&&&&&&&&& 1[2],2[1]&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 2,5,2  shanghai&&&&&&&&&&& 2[1]&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 3  tom&&&&&&&&&&&&&&&&&& 1[1]&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 1    以live 这行为例我们说明一下该结构:live在文章1中出现了2次,文章2中出现了一次,它的出现位置为&#,2”这表示什么呢?我们需要结合文章号和出现频率来分析,文章1中出现了2次,那么&#”就表示live在文章1中出现的两个位置,文章2中出现了一次,剩下的就表示live是文章2中第 2个关键字。    以上就是lucene索引结构中最核心的部分。我们注意到关键字是按字符顺序排列的(lucene没有使用B树结构),因此lucene可以用二元搜索算法快速定位关键词。    实现时 lucene将上面三列分别作为词典文件(Term Dictionary)、频率文件(frequencies)、位置文件 (positions)保存。其中词典文件不仅保存有每个关键词,还保留了指向频率文件和位置文件的指针,通过指针可以找到该关键字的频率信息和位置信息。     Lucene中使用了field的概念,用于表达信息所在位置(如标题中,文章中,url中),在建索引中,该field信息也记录在词典文件中,每个关键词都有一个field信息(因为每个关键字一定属于一个或多个field)。    为了减小索引文件的大小,Lucene对索引还使用了压缩技术。首先,对词典文件中的关键词进行了压缩,关键词压缩为&堉?缀长度,后缀&,例如:当前词为“阿拉伯语”,上一个词为“阿拉伯”,那么“阿拉伯语”压缩为&3,语&。其次大量用到的是对数字的压缩,数字只保存与上一个值的差值(这样可以减小数字的长度,进而减少保存该数字需要的字节数)。例如当前文章号是16389(不压缩要用3个字节保存),上一文章号是16382,压缩后保存7(只用一个字节)。     下面我们可以通过对该索引的查询来解释一下为什么要建立索引。  假设要查询单词 “live”,lucene先对词典二元查找、找到该词,通过指向频率文件的指针读出所有文章号,然后返回结果。词典通常非常小,因而,整个过程的时间是毫秒级的。  而用普通的顺序匹配算法,不建索引,而是对所有文章的内容进行字符串匹配,这个过程将会相当缓慢,当文章数目很大时,时间往往是无法忍受的。本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/geekwang/archive//3410187.aspx
阅读(...) 评论()
努力才能前进,勤耕博客才能看远

我要回帖

更多关于 欧陆词典怎么读取词库 的文章

 

随机推荐