看Lucene源码必须知道的基本规则和算法

  上中学的时候写作文,最喜欢的季节我都是写冬天。虽然是因为写冬天的人比较少,那时确实也是对其他季节没有什么特殊的偏好,反而一到冬天,自己皮肤会变得特别白。但是冬天啊,看到的只有四季常青盆栽:瓜栗(就是发财树,好吧,算我矫情,反正我不喜欢这个名字),绿萝,永远看不到它开花的巴西铁,富贵竹,散尾葵……过年的时候家里的杜鹃就开花了,零星的几朵小花儿更突显了这个季节的凄凉。红掌,蝴蝶兰总是美美的在那里,开不败却看不到生机。插到水里的勿忘我,洋桔梗,看到他们也只会联想到过几天他们会枯萎的命运。春天来了,先是迎春花,然后是桃花,玉兰。到了四月,红叶碧桃,紫荆,樱花,紫叶李,垂丝海棠……最喜欢丁香花的味道~~再过几日,郁金香和牡丹也该开了。桃之夭夭,灼灼其华。果然,阳光下这些花儿是流光溢彩的。人生的悲哀不是短暂的快乐过后无尽的痛苦,而是从来没让自己快乐过。想想小鲜肉看的《熊出没-雪岭熊风》电影,熊二没有再次遇到团子之前的魂儿不守舍,与团子经历过精彩之后,虽然别人什么都不记得了,所有的场景回到了最初,熊二心里却是满足和平静。就像这些花儿,虽然是花开不多时,但怒放过的青春总好过冬青一日和一生毫无区别(中学作文里还总是在赞扬它冬天还是绿的呢[此处有表情])。大概现在和中学的时候最大的区别,就是那时候的人生观更多的是受父母的影响。父母都是医生,铁饭碗,稳定是一成不变的追求。离父母越来越远,活得越来越像自己,才发现自己的人生需要冬天的期待与思考,春天花的妖娆,夏天叶的茂盛,秋天果实的沉重。谁规定的第一个季节是春天?我的人生第一个季节就不是

  下面介绍一些Lucene使用基本规则和算法。这些规则和算法的选择,都和Lucene和支持TB级的倒排索引有关。

  前缀后缀规则(Prefix+Suffix):在Lucene的反向索引中,要保存词典的信息,所有的词再词典中是按照字典顺序进行排列的,然后词典中包含了文档中的几乎所有的词,并且有的词还是很长的,这样索引文件会非常的大,所谓前缀后缀规则,就是某个词和前一个词有共同的前缀的时候,后面的词仅仅保存前缀在词中的偏移(offset),和剩下的部分(后缀)。

  比如:北京天安门  这个词词典里通常都会包含北京  天安门  北京天安门  这三个词。北京和北京天安门由于前缀相同,在字典表里会相邻存储,两个词存成  北京2天安门   ,这样存比北京北京天安门   省空间。

  差值规则(Delta):在lucene的反向索引中,需要保存很多整形数字的信息,比如文档ID号,比如词在文档中的位置等等。整形数字是以可变长整型的格式存储的。随着数值的增大,每个数字占用的比特位增多。所谓差值规则就是先后保存两个整数的时候,后面的整数仅仅保存和前面整数的差即可。多唠叨两句:因为看到有的哥哥们定义数据库字段的时候总是想都不想就用varchar,MD5的结果也用varchar[汗]。MD5的结果长度是固定的,没有必要用varchar来节省空间。定长的char效率会高些。

  LZ4算法(Realtime Compression Algorithm):在操作系统(linux/freeBSD),文件系统(OpenZFS),大数据(Hadoop),搜索引擎(Lucene/solr),数据库(Hbase)等中都可以看到它的身影,很通用。压缩/解压速度快。

  跳跃表规则(Skip list):跳跃表是一种数据结构。额~~,要不能用几句话把它介绍明白,真不好意思说自己有那么多算法专利。首先使用跳跃表的前提是因为搜索引擎的索引数据是高度有序的。打个比方:我从北京回老家青州市可以做北京南到青岛的动车或者高铁。它们的路线是一样的,后者贵100块钱。贵在哪里呢?后者停的站少,就是跳站了。有的高铁到青州市不停。我只能在前一站淄博或者后一站潍坊下车,然后坐慢车去青州市。跳跃表就是这个原理。所有的搜索数据存在一个链表里,这就是慢车(最传统的绿皮车)。然后新加一个链表,存的数据中间有间隔(K字头车)。这时候我不得不说一个原则:所有原来的时间复杂度是delta(找这个符号比较费劲,我就直接用英文了,记住它是很有好处的,去米国总免不了和这个航空公司打交道~~) n的算法,期待的终极优化后的结果基本都是 delta  log n。所以只有两层的话,时间复杂度是达不到要求的。怎样达到要求呢?最终要形成一棵树。怎么形成一棵树呢?加层呗。加大跳站的间隔,T字头车,D字头车,G字头车。一直到中间是所有的站,形成了一个root。树形结构就形成了。时间复杂度变成了delta log n[耶][耶] Lucene3.0之前很多地方使用这种数据结构来提高查找速度。但是因为它对模糊查询的支持不太好,现在Lucene改用FST了。

  关于delta再多唠叨两句:它是希腊语的第四个字母,大写是△。我这么懒,不愿意去拷贝一个小写字母到这里,大写字母打出来也是因为我直接改用日语输入法,打个[三角形]出来的~~。上面提到差值规则和时间复杂度都用到了delta。因为在数学或者物理中大写的Δ用来表示增量符号。而小写通常在高等数学中用于表示变量或者符号。所以差值规则里用到了它大写的含义,时间复杂度里用到了它小写的含义。

  有限自动机算法(FST,Finite State Transducer):通过输入有序字符串构建最小有向无环图。通过共享前缀来节省空间,内存存放前缀索引,磁盘存放后缀词块。Lucene的源码中可以看到它的具体实现。

  Lucene之所以有那么频繁的版本升级,我以前还专门追剧似的关心这个升级,是因为这里面有一个问题的发生与解决的过程,举个简单的例子:在Windows系统中一个文件夹只能存放2W多个文件,在1W多个文件以后写入速度会急剧下降,Lucene这样处理TB级数据的系统更要考虑数据量和性能的关系和权衡。

  有限自动机是Lucene的核心查找算法,理解需要一定的时间。下面介绍Lucene的打分相关规则,这部分很容易理解。

  文档权重(Document boost):在索引时给某个文档设置的权重值。

  域权重(Field boost):在查询的时候给某个域设置的权重值。

  调整因子(Coord):基于文档中包含查询关键词个数计算出来的调整因子。一般而言,如果一个文档中相比其它的文档出现了更多的查询关键词,那么其值越大。

  逆文档频率(Inerse document frequency):基于Term的一个因子,存在的意义是告诉打分公式一个词的稀有程度。其值越低,词越稀有(这里的值是指单纯的频率,即多少个文档中出现了该词;而非指Lucene中idf的计算公式)。打分公式利用这个因子提升包含稀有词文档的权重。

  长度归一化(Length norm):基于域的一个归一化因子。其值由给定域中Term的个数决定(在索引文档的时候已经计算出来了,并且存储到了索引中)。域越的文本越长,因子的权重越低。这表明Lucene打分公式偏向于域包含Term少的文档。

  词频(Term frequency):基于Term的一个因子。用来描述给定Term在一个文档中出现的次数,词频越大,文档的得分越大。

  查询归一化因子(Query norm):基于查询语句的归一化因子。其值为查询语句中每一个查询词权重的平方和。查询归一化因子使得比较不同查询语句的得分变得可行,当然比较不同查询语句得分并不总是那么易于实现和可行的。

  如需转载,请注上我的原文链接: http://www.cnblogs.com/xiexj/p/6683439.html  谢谢哦~~

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏数据小魔方

R语言数据地图——全球填色地图

今天这篇是昨天美国地图的续篇,同样的方法技巧,不同的对象。 整个过程以及代码并没有太大差别,只要拿到世界地图素材,根据之前的代码,自己修改参数和指标名称以及引用...

2947
来自专栏数据结构与算法

Day2上午解题报告

预计分数:100+0+60=160 实际分数:100+0+60=160 mmpT1数据错了。。。 T1遭遇 题目描述 你是能看到第一题的 friends呢。 —...

4004
来自专栏简书专栏

基于Numpy的统计分析实战

标题中的英文首字母大写比较规范,但在python实际使用中均为小写。 2018年7月27日笔记 学习内容: 1.从文件中读取数据 2.将数据写入文件 ...

1012
来自专栏一心无二用,本人只专注于基础图像算法的实现与优化。

SSE图像算法优化系列八:自然饱和度(Vibrance)算法的模拟实现及其SSE优化(附源码,可作为SSE图像入门,Vibrance算法也可用于简单的肤色调整)。

  Vibrance这个单词搜索翻译一般振动,抖动或者是响亮、活力,但是官方的词汇里还从来未出现过自然饱和度这个词,也不知道当时的Adobe中文翻译人员怎么会这...

3908
来自专栏每日一篇技术文章

SceneKit_入门13_骨骼动画

1.创建工程(略) 2.加载场景文件(略) 3.添加框架SceneKit/Scenekit.h 4.创建场景资源对象

912
来自专栏Crossin的编程教室

身份证号码校验算法

1、数字含义 中国大陆第二代身份证号码由18位数据或字母组成,每位数据都有特定的含义,结果如下: ? 每组数字都有不同的含义: 第1至2位数字代表所在省(直辖市...

2979
来自专栏CDA数据分析师

用SPSS做数据分析?先弄懂SPSS的基础知识吧

1、SPSS数据分析的流程 ? 2、SPSS特性: ? 3、数据的编辑: 1 常量 数值型常量:除了普通写法外还可以用科学计数法,如:1.3E18; 字符型常量...

19610
来自专栏人工智能LeadAI

讨厌算法的程序员 2 | 证明算法的正确性

第1篇介绍了插入排序算法,这里要提出一个问题:学习算法仅仅是积累一个又一个的算法实现吗? 当然不是。比算法本身更重要也更基础的,是对算法的分析:能够证明其正确性...

3355
来自专栏TensorFlow从0到N

讨厌算法的程序员 2 - 证明算法的正确性

第1篇介绍了插入排序算法,这里要提出一个问题:学习算法仅仅是积累一个又一个的算法实现吗? 当然不是。比算法本身更重要也更基础的,是对算法的分析:能够证明其正确...

2805
来自专栏小樱的经验随笔

零基础学并查集算法

并查集是我暑假从高手那里学到的一招,觉得真是太精妙的设计了。以前我无法解决的一类问题竟然可以用如此简单高效的方法搞定。不分享出来真是对不起party了。(pa...

4618

扫码关注云+社区