看Lucene源码必须知道的基本概念

  终于有时间总结点Lucene,虽然是大周末的,已经感觉是对自己的奖励,毕竟只是喜欢,现在的工作中用不到的。自己看源码比较快,看英文原著的技术书也很快。都和语言有很大关系。虽然咱的技术不敢说是部门第一的,说到日语和英语,倒是无人能出其右的。额~~,一个做技术的,感觉自己好弱啊。对语言,只是天赋而已。对技术,却是痴迷。虽然有人跟我说我不做管理白瞎了我这个人儿。但是我就一心想做技术,如果到了40岁,做技术没人要的话。我就去硅谷编代码去,毕竟硅谷的同事都说我技术挺好的,相信找个技术活儿还是不成问题的。话说现代人确实是比古人努力多了,那凿壁偷光的匡衡也没近视,现代不带眼镜才是稀有。多情应笑我早生华发的苏轼写《念奴娇》的时候至少也40岁了吧,现代却都是少白头。上班的人不易,公司也不易。所以之前公司晚上8点之后能打车报销的时候我也没打过车,加班餐也不怎么吃。毕竟我们乐视是一个有理想的公司,大家都是在为理想努力着。乐视不仅是一个生态的企业,而且是个讲求创新的企业,在人工智能方面也是一直领先和执着的。我其实挺看好乐视的前景的,就是,实在话,互联网技术上比BAT差距挺大的。

下面的一些基本概念不但有助于看源码,在使用像solr这样的搜索引擎框架的时候还可以知道自己的配置都做了些什么事情。我在定义这些概念的时候也都有自己的理解和思考。

  反向索引:全文索引将半结构化或者全文数据进行结构化,保存为字符串到文件的映射。因为这是一个文件到字符串的反向过程,被称为反向索引。

  倒排表:上面说的字符串到文件的映射,这个文件实际上在lucene中是一个文档链表,称为倒排表(Posting List)。

  分词组件(Tokenizer):在调用lucene建索引的时候,要先new一个Field,然后添加到Document里去。这个Field要成为索引的第一步就是进入分词组件进行分词:Tokenizer主要做了三件事1>分成一个个单独的单词 2>取出标点符号 3>去除停用词(停用词是没有实际意义的词,如:的,儿。每一种语言的分词组件,都有自己的停用词库)

  词元(Token):经过分词组件的三步处理,得到的结果就是词元了。

  Stemming:对于英语来说,词元的下一步处理是通过语言处理组件Linguistic Processor来将其变成小写,然后通过某种算法将其变成词根,比如:复数形式变成词根形式,进行时和完成时变成词根形式(如果有不知道什么是词根的童鞋,可以去问英语老师哦~~)。这种变化过程叫做Stemming。

  Lemmatization:这个也是应用于外语的,如果你做的是中文搜索,在配置的时候,发现你的搜索引擎走了这一步,你其实是在无用功哦~~。因为在英语中,有一些复数啊,完成时啊,进行时啊  变化是不规则的,不能通过算法来解决,就要基于词典了。这种基于词典的词根化过程叫做Lemmatization。但是基于算法的计算总归要快于基于匹配的算法,所以有些其实用Lemmatization也能达到最终效果,但是最好用Stemming。

  词(Term):经过上面词根化后的词成为Term。

  这里值得注意的是,英语中不管输入一个单词的什么形式,有了词根化,都可以把带有各种形式的都搜索出来。汉语虽然没有这一步,但是汉语中有近义词的概念,它的实现和Lemmatization大体相同,都是基于词典的。但是对它的处理要采用自己配置过滤器的方式。

  索引组件(Indexer):Term要通过Indexer来最终添加到倒排表中。Indexer主要做了两件事:1>排序 2>合并。最后得到的倒排索引是一个大链表,链表里的每个Term都是一个小链表,链表里存了在各个文档中出现的词频。结构大体是下图的样子:

  语法树:我们输入的查询内容是有语法的。在汉语中这种语法体现的不明显,但在英文中,比如 Lucy AND Lily OR Andy Not Tom就会形成一个由关键词和普通词组成的语法树,当然语法树中的单词也是需要词根化的。之后,将包含Lucy Lily的链表进行取交集(AND操作),得到文档再和包含Andy的合并(OR 操作),再将此链表与包含Tom的链表进行差(NOT操作),最后对得到的链表进行相关度排序,得到结果,语法树的逻辑上大概长成下面的样子:

  将上面几个简单的概念串联起来其实就是索引和搜索的过程了。

  索引过程:全文数据经过语法分析和语言处理形成词(Term),词再排序和合并成倒排链表进行存储(可以存内存,也可以持久化到硬盘)

  搜索过程:将用户输入经过语法分析和语言处理形成词(Term),通过语法分析得到语法树,找出所有包含语法树的词的文档,进行交,并,差操作得到结果文档,相关度排序得到最终结果。

  

  这是一个索引的文件的磁盘存储截图。文件夹下所有文件构成了lucene的索引(注意后面的文件大小)。索引中又有些必须知道的概念。

  段(Segment):一个索引可以包含多个段,之间是独立的,可以合并。具有相同前缀的文件属于同一个段,图中显示了_1s和_b两个段。segments.gen和segments_1是段的元数据文件(保存属性的)

  文档(Document)是建索引的基本单位,存在段中。新添加的文档单独保存在新生成的段中,随着段的合并可以将不同的文档合并到同一个段中。

  segments_N文件:保存了此索引包含多少个Segment,每个段包含多少Document.

  .fnm文件:保存了此段包含了多少field,每个field的名称及索引方式

  .fdx,.fdt文件:保存了此段包含的Document, 每篇Document里的每个field存了什么。

  .tvx,.tvd,.tvf文件:保存了此段包含多少Document,每篇包含多少Field,每个field包含了多少term,每个term具体信息。

  .tis,.tii文件:保存了此段的Term按字典顺序的排序。

  .frq文件:保存了倒排表,就是每个Term的文档ID列表。

  .prx文件:保存了倒排表中每个词在包含词的文档中的位置

Lucene源码的更多相关文章

  1. 细说Lucene源码(一):索引文件锁机制

    大家都知道,在多线程或多进程的环境中,对统一资源的访问需要特别小心,特别是在写资源时,如果不加锁,将会导致很多严重的后果,Lucene的索引也是如此,lucene对索引的读写分为IndexReader ...

  2. Lucene 源码分析之倒排索引(三)

    上文找到了 collect(-) 方法,其形参就是匹配的文档 Id,根据代码上下文,其中 doc 是由 iterator.nextDoc() 获得的,那 DefaultBulkScorer.itera ...

  3. 一个lucene源码分析的博客

    ITpub上的一个lucene源码分析的博客,写的比较全面:http://blog.itpub.net/28624388/cid-93356-list-1/

  4. lucene源码分析的一些资料

    针对lucene6.1较新的分析:http://46aae4d1e2371e4aa769798941cef698.devproxy.yunshipei.com/conansonic/article/d ...

  5. 看Lucene源码必须知道的基本概念

    终于有时间总结点Lucene,虽然是大周末的,已经感觉是对自己的奖励,毕竟只是喜欢,现在的工作中用不到的.自己看源码比较快,看英文原著的技术书也很快.都和语言有很大关系.虽然咱的技术不敢说是部门第一的 ...

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

    上中学的时候写作文,最喜欢的季节我都是写冬天.虽然是因为写冬天的人比较少,那时确实也是对其他季节没有什么特殊的偏好,反而一到冬天,自己皮肤会变得特别白.但是冬天啊,看到的只有四季常青盆栽:瓜栗(就是发 ...

  7. lucene源码分析(1)基本要素

    1.源码包 core: Lucene core library analyzers-common: Analyzers for indexing content in different langua ...

  8. Lucene 源码分析之倒排索引(一)

    倒排索引是 Lucene 的核心数据结构,该系列文章将从源码层面(源码版本:Lucene-7.3.0)分析.该系列文章将以如下的思路展开. 什么是倒排索引? 如何定位 Lucene 中的倒排索引? 倒 ...

  9. lucene源码地址

    http://archive.apache.org/dist/lucene/java/

随机推荐

  1. hadoop系列 第二坑: hive hbase关联表问题

    关键词: hive创建表卡住了 创建hive和hbase关联表卡住了 其实针对这一问题在info级别的日志下是看出哪里有问题的(为什么只能在debug下才能看见呢,不太理解开发者的想法). 以调试模式 ...

  2. 可长点心吧-sort

    sort #<algorithm> 用的时候一定是 从 第一个(你想要排序的范围内的) 到 最后一个+1 真的错了不止一次了 真的长点心吧

  3. matlab padarray函数

    1 padarray功能:填充图像或填充数组.用法:B = padarray(A,padsize,padval,direction)      A为输入图像,B为填充后的图像, padsize给出了给 ...

  4. CTS 如何处理 gating clock 和 generated clock

    1. CTS 时会将 ICG cell 作为 implicit nostop pin 处理,直接穿透,以 ICG cell 后面的 sink 点作为真正的 sink 来长 tree 2. CTS 时会 ...

  5. AI 隐马尔科夫模型

    隐马尔科夫模型(Hidden Markov Model,简称HMM),

  6. Ubuntu触摸屏校准

    我是在ubuntu系统中使用触摸屏,我的是两块屏幕一个是触摸屏幕一个是普通的屏幕,触摸屏使用需要校准,所以要直接入一个触摸屏,或者两个屏幕是复制的关系,不能是扩展. 1.安装已下的两个软件,有可能第一 ...

  7. nginx-haproxy-lvs功能和性能对比 nginx - max-fail + 调度算法

    优点(性能和功能两方面分析) 缺点 lvs 工作在4层,可以对http,MySQL等服务负载均衡.负责流量的分发,对io,cpu,mem的消耗少 功能比较少,没有正则匹配的功能 nginx 工作在7层 ...

  8. Java使用数字证书加密通信(加解密/加签验签)

    本文中使用的Base64Utils.java可参考:http://www.cnblogs.com/shindo/p/6346618.html 证书制作方法可参考:http://www.cnblogs. ...

  9. XML转换为对象/Javabean

    將XML轉換為對象 /** * xml转换成JavaBean * @param xml * @param c * @return */ public static <T> T conver ...

  10. Luogu3352 ZJOI2016 线段树 概率、区间DP

    传送门 考虑对于每一个位置\(i\),计算所有可能的结果出现的概率. 定义一个区间\([l,r]\)为对于\(x\)的极大区间,当且仅当\(\max \limits _{i=l}^r \{a_i\} ...