《lucene原理与代码分析》笔记
1.全文索引相对于顺序扫描的优势:一次索引,多次使用
2.创建索引的步骤:
(1)要索引的原文档
(2)将原文档传给分词组件(Tokenizer)
分词组件会做如下事情:(此过程称为Tokenize)
a.将文档分成一个一个的单词
b.去除标点符号
c.去除停词(Stop Word) **停词就是语句中无意义的词汇,英语中比如 the is of
每一种分词组件(Tokenize)都有一个停词集合
经过分词组件分词后得到的结果称为(词元)Token
(3).将得到的词元传给语言处理组件(Linguistic Processor)
语言处理组件主要对词元进行一些同语言相关的操作
对于英语,语言处理组件主要做如下处理:
a.变为小写(Lowercase)
b.将单词缩减为词根形式 如cars -> car ,这种操作叫做 stemming
c.将单词转变为词根形式 如drove -> drive 这种操作为lemmatization
stemming与lemmatization的异同:
相同:都使单词变成词根形式
不同:两者的方式不同,一个是缩减,一个是转变
两者的算法不同 ,前者主要某种固定的算法来做这种缩减
后者主要采用保存某种字典的方式做这种转变
两者不是互斥关系,是有交集的,有的单词可以用两种方法达到同一种效果,比如 driving
语言处理组件处理后得到的是词(term).
(4).将得到的词(term)传给索引组件(Indexer)
a.利用得到的词创建一个字典 (term,documentId)
b.对字典按字母排序进行排序
c.合并相同的词(Term)成为文档倒排(Posting List)链表
document frequency 即文档频次,表示总共有多少文件包含此词
frequency 即词频率,表示文档中包含了几个此词
3.对索引进行搜索
(1)用户输入查询语句 and or not 查询语句有很多语法。举例 lucene AND learned NOT hadoop
(2)对查询语句进行词法分析,语法分析,语言处理。
a.词法分析主要用来识别单词和关键字,如果关键字错误,则视为正常单词 如lucene AMD .. 则视为AMD 这个单词
b.语法分析主要是根据查询语句的语法规则形成一颗语法树
c.语言处理与建立索引的语言处理基本相同
(3)搜索索引,得到满足语法树的文档
a.首先,在反向索引表中,分别找出包含lucene , learn , hadoop 的文档列表
b.其次,对包含lucene , learn 的链表进行合并操作,得到既包含lucene 又包含learn的文档链表
c.然后,将此链表与hadoop的文档链表进行差操作,去除包含hadoop的文档,从而得到既包含lucene ,又包含learn ,但是不包含hadoop的文档链表
d.得到的链表就是我们需要的文档
(4)根据得到的文档和查询语句的相关性,对结果进行排序。
判断文档之间的关系:
首先要找出哪些词(term)对文档之间的关系最重要,然后判断这些词之间的关系
(4.1)找出词对文档的重要性的过程称为计算词的权重(term weight)问题
(A)影响计算权重的两个因素:
(I)term frequency 表示term在文档中出现多少次,tf越大说明越重要
(II)document frequency 表示有多少文档包含此term df越大说明越重要 但是次数太多,比如this ,该元素会有所调整
(B)判断term之间的关系从而得到文档相关性的的过程,也即向量空间模型的算法。
第三章 : lucene的索引文件格式
lucene索引结构是有层次结构的,具体如下:
(1)索引 : 索引全部是是放在同一个文件夹中,这些内容构成了一个完整的lucene索引
(2)段(segment):一个索引可以包括很多段,段与段之间是独立的,新添加新文档可以生成新的段,段与段可以合并
具有相同前缀文件的属于同一段,如图中共两个段"_0","_1";
segments.gen 和 segment_5是段的数据文件,也即它们保存了段的属性信息
(3)文档(document):文档是建立索引的基本单位,不同的文档保存在不同的段中,一个段可以包括多篇文档
新添加的文档是单独保存在新生成的段中,随着段的合并,不同的文档合并到同一个段中。
(4)域(field):一篇文档包含不同类型的信息,可以分开索引,比如正题,时间,正文等,都可以保存在不同的域中,
不同域的索引方式可以不同
(5)词(term):词是索引的最小单位,是经过词法分析和语言处理后的字符串
lucene的索引结构中,既包括了正向信息,也包括了反向信息
正向信息:按层次保存了从索引,一直到词的包含关系,索引(Index)-->段(segment)-->文档(document)-->域(field)-->词(term);
每个层次都包含了本层次的信息以及下层次的元信息
包含正向信息的文件有:
segment_N保存了此索引包含多少段,每段包含了多少个文档
XXX.fnm保存了此段包含了多少域,每个域的名称以及索引方式
XXX.fdx XXX.fdt 保存了此段包含的所有文档,每个文档包含了多少域,每个域放了那些信息
XXX.tvx XXX.tvd XXX.tvf 保存了此段包含的所有文档,每个文档包含了多少域,每个域包含了那些词,每个词的字符串位置等信息
反向信息:保存了字典到倒排表的映射,词(term)--> 文档(document)
XXX.tis XXX.tii 保存了词典,也即此段包含的所有的词按字典顺序的排序
XXX.frq 保存了倒排表,也即包含每个词的文档Id列表
XXX.prx 保存了倒排表中每个词在包含此词的文档中的位置
lucene 如何表示String :首先是一个Vint来表示此字符串包含的字数的个数,接着便是utf-8 编码的字符序列的chars
lucene为了使信息的存储空间更小,访问速度更快,采用了一些技巧:
1.前缀后缀原则:当某一个词和前面一个词有共同的前缀的时候,后面的词仅仅保留前缀在词中的偏移,以及出前缀外的字符串
2.差值原则 :先后保存两个整数的时候,后面的整数仅仅保存和前面整数的差值即可。
3.或然跟随原则: lucene索引结构用一个标志位来表示某个值A后面可能存放某个值B 这样会浪费一个byte的空间,实际上一个bit就够了
4.跳跃表规则:元素按顺序排列,按跳跃间隔和跳跃层次提交查找速度
标准化因子在索引过程中总的计算:包括三个参数,
(1)document boost 此值越大,说明此文档越重要
(2)field boost 此值越大,说明此域越重要
(3)一个域中包含的term越多,也即文档越长,此值越小,文档越短,此值越大
文档的删除主要有三种方式:
indexWriter.deleteDocuments(Term ,term)所有包含此词的文档都会被删除
indexWriter.deleteDocuments(Query , query) 所有能满足此查询的文档都会被删除
indexReader.deleteDocuments(int docNum) 删除此id的文档
归根结底还是按照文档号删除
删除文档既可以用reader,也可以用writer
不同点:reader进行删除后,可以马上生效
而用writer删除后,会被缓存在deleteinRAM以及deleteFlushed中,只要写入到索引文件,当indexReader再次打开时,才能够看到
deleteinRAM与deleteFlushed
有些版本的lucene对文档的删除是支持多线程的,当用indexWriter删除文档的时候,都是缓存在deleteinRAM中的,
直到flush,才将删除的文档写入到索引文件中,如果flush的过程中,另一个线程又有文档删除的话,流程怎么样呢?
一般这样进行,在flush的时候,首先在同步的方法pushDeletes中,将deleteinRAM全部加到deleteFlushed中,然后将deleteinRAM
清空,退出同步方法,于是在flush的线程就向索引文件写入deleteFlushed中的删除文档的同时,其他线程新删除的文档则 添加到新的
deleteinRAM中去,直到下次flush才写入索引文件。
关闭indexwriter 会进行两个操作:
1.将索引信息由内存写入硬盘
2.进行段合并
indexReader打开一个索引,就好像对此索引照了一张像,无论背后索引如何改变,此indexReader在被重新打开之前,看到的信息总是相同的
lucene的文档号仅仅对打开的某个reader有效,当再打开一个reader的时候,不同的reader的同一个文档号
就可能不同,因此文档号要在reader关闭之前应用。
BoostingQuery 包括三个成员变量:
1.Query match:结果集必须满足的查询条件
2.Query context:此查询对象不对结果集产生任何影响,仅在当文档包括context查询的时候,将文档打分乘以boost
3.float boost
CustomScoreQuery 包括两个成员变量:
1.Query subQuery 子查询
2.ValueSourceQuery[] valSrcQueries :其他信息源
举例:doc.add("context", .......);
doc.add("scorefield","10","Filed.Store.NO","Filed.Index.NOT_ANALYZED");
将来进行查询的时候,普通查询 TermQuery termQuery = new TermQuery(new Term("context","apple"));
得到的结果为包含apple多的打分就高.
如果按CustomScoreQuery进行查询:TermQuery subQuery = new TermQuery(new Term("context","apple"));
FiledScoreQuery scorefield = new FieldScoreQuery("scorefield",FiledScoreQuery.Type.BYTE);
CustomScoreQuery query = new CustomScoreQuery(subQuery,scorefield);
则文档因为设置数据源为10而变得最高
不同Analyzer的就是 组合不同的tokenizer 和tokenfilter得到最后的TokenStream
1.ChineseAnalyzer 按字分词,并过滤停词,标点,英文
This year ,persidetn Hu 科学发展观 --> year president hu 科 学 发 展 观
2.CJKAnalyzer 每两个字组成一个词,并过滤停词,标点,英文
--> year president hu 科学 学发 发展 展观
3.PorterStemAnalyzer 将转为小写的token ,利用porter算法进行stemming
4.SmartChineseAnalyzer 分句子,句子中分词组,用porter算法进行stemming,去停词
5.SnowBallAnalyzer 标准分词器,标准过滤器,转换为小写,去停词,利用porter算法进行stemming
《lucene原理与代码分析》笔记的更多相关文章
- HTML+CSS笔记 CSS笔记集合
HTML+CSS笔记 表格,超链接,图片,表单 涉及内容:表格,超链接,图片,表单 HTML+CSS笔记 CSS入门 涉及内容:简介,优势,语法说明,代码注释,CSS样式位置,不同样式优先级,选择器, ...
- CSS笔记--选择器
CSS笔记--选择器 mate的使用 <meta charset="UTF-8"> <title>Document</title> <me ...
- HTML+CSS笔记 CSS中级 一些小技巧
水平居中 行内元素的水平居中 </a></li> <li><a href="#">2</a></li> &l ...
- HTML+CSS笔记 CSS中级 颜色&长度值
颜色值 在网页中的颜色设置是非常重要,有字体颜色(color).背景颜色(background-color).边框颜色(border)等,设置颜色的方法也有很多种: 1.英文命令颜色 语法: p{co ...
- HTML+CSS笔记 CSS中级 缩写入门
盒子模型代码简写 回忆盒模型时外边距(margin).内边距(padding)和边框(border)设置上下左右四个方向的边距是按照顺时针方向设置的:上右下左. 语法: margin:10px 15p ...
- HTML+CSS笔记 CSS进阶再续
CSS的布局模型 清楚了CSS 盒模型的基本概念. 盒模型类型, 我们就可以深入探讨网页布局的基本模型了.布局模型与盒模型一样都是 CSS 最基本. 最核心的概念. 但布局模型是建立在盒模型基础之上, ...
- HTML+CSS笔记 CSS进阶续集
元素分类 在CSS中,html中的标签元素大体被分为三种不同的类型:块状元素.内联元素(又叫行内元素)和内联块状元素. 常用的块状元素有: <div>.<p>.<h1&g ...
- HTML+CSS笔记 CSS进阶
文字排版 字体 我们可以使用css样式为网页中的文字设置字体.字号.颜色等样式属性. 语法: body{font-family:"宋体";} 这里注意不要设置不常用的字体,因为如果 ...
- HTML+CSS笔记 CSS入门续集
继承 CSS的某些样式是具有继承性的,那么什么是继承呢?继承是一种规则,它允许样式不仅应用于某个特定html标签元素,而且应用于其后代(标签). 语法: p{color:red;} <p> ...
- HTML+CSS笔记 CSS入门
简介: </span>年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时间,决心开发一个新的<span>脚本解释程序</span>,作为ABC语言的一种继承. & ...
随机推荐
- js随笔,css和js禁止网页选择文本,table的class样式使得td的class样式失效,jquery获得元素坐标
css使用user-select,user-select不是W3C标准,浏览器支持不完整:user-select有两个值,none用户不可以选择文本,text用户可以选择文本 body{-moz-us ...
- Linux学习笔记<三>
<1>查看本机的IP地址 命令:ifconfig -a 机器的ip地址是:(inet 地址:172.16.163.57 ) <2>单独查看内存使用情况的命令:free -m 查 ...
- javascript字符串截取的substring、substr和slice
本文详细的介绍了javascript中substring().substr()和slice()三个JS字符串截取的方法,substring()方法用于提取字符串中介于两个指定下标之间的字符.subst ...
- C++ 生成 dll 和调用 dll 的方法实例(转)
1)生成dll 建立两个文件 xxx.h , xxx.cpp xxx.h内容如下: #ifdef BUILD_XXX_DLL#define EXPORT __declspec(dllexport)#e ...
- ecshop订单-》待付款,待发货,待收货,收货确认
// 订单 待付款.待发货.待收货.确认收货 public function get_serch_order($type/*,$limit_statrt,$limit_end,$serch*/){ $ ...
- Robot Framework--11 RF结合Jenkins
转自:http://blog.csdn.net/tulituqi/article/details/17846463 为什么我们要引入RF?其实最初我们引入RF是为了能够快速的开展自动化验收测试,为敏捷 ...
- php Hash Table(一) Hash Table的结构
关于Hash Table专题: 一直想深入理解一下php的hash table的实现,以前一直是星星点点的看看,从未彻底的总结过,那就从这个专题开始吧! 主要想总结几个部分:hashtable结构,h ...
- 使用EntityFramework6.1的DbCommandInterceptor拦截生成的SQL语句
开始 EF6.1也出来不少日子了,6.1相比6.0有个很大的特点就是新增了System.Data.Entity.Infrastructure.Interception 命名空间,此命名空间下的对象可以 ...
- 缺少索引导致的服务器和MYSQL故障。
故障现象: 网站访问缓慢. 数据库RDS: CPU满,连接数满,其他值都是空闲. apache服务器:CPU正常,IO正常,流量报警,内存爆满. 解决思路: 一.没遇到过此情况,一脸懵逼. 二.请教大 ...
- YII2 实现后台操作记录日志(转)
一.连接linux服务器,创建数据文件 php yii migrate/create user_log 二.修改数据文件 console/migrations/m150721_032220_admin ...