Lucene里经常被聊到的几个话题
lvpei.cnblogs.com.自己总结的Lucene熟悉而暧昧的几个问题。
1、索引及搜索的概念
将原始数据处理成一个高效的交差引用的查找结构以便于快速的搜索。索引结构是指快速随机访问存于其内部的关键词的数据结构。
搜索是在一个索引中查找单词来找出它们所出现的文档的过程。支持单个和多个词汇的查询,短语查询,通配符,结果分级和排序。
2、lucene的核心类
核心索引类
IndexWriter唯一能写索引的类 索引的写入和索引的整体的维护 合并,优化
Analyzer:分析文本内容,提取关键字
Document:一个Document代表字段的集合
Field:每个Document含有一个或多个字段,具体化为Field类。是否存储,是否索引,是否分词
核心搜索类
IndexSearcher以只读方式打开索引,提供几个搜索方法,最简单的接受单个Query对象做为参数并返回一个Hits 对象。
Term是搜索的基本单元。与Field对象类似,它由一对字符串元素组成:字段的名称和字段的值。
Query q = new TermQuery(new Term(“contents”, “lucene”));
Hits hits = is.search(q);
Query的几个子类实现就是lucene的几种搜索方式:TermQuery、BooleanQuery,模糊查询PhraseQuery,前缀查询PrefixQuery, PhrasePrefixQuery, 范围搜索RangeQuery
通配符搜索WildcardQuery
Hits类是一个搜索结果(匹配给定查询的文档)文档队列指针的简单容器。并不从索引中加载所有匹配文档。
3、提高索引效率。
可以合并索引来减少目录索引文件的数量,以提高处理索引的效率。
IndexWriter的optimize()对索引目录和缓存目录下所有的segment优化,Lucene只需要打开一个索引文件加载,效率会大大提高。
优化也会带来一些损失:耗费更多的内存和磁盘空间
MERGE_FACTOR用于子索引(Segment)合并,相当于ORAl数据库中对大批量的数据插入操作优化,值越大,索引效率越快。
RAMDirectory把一个普通的index完全读取到内存中,比真正的文件系统快很多.
尽可能对字段进行索引来提高查询速度.
4、lucene2.1到2.4的变动
IndexWriter 的构造器 参数多了一个字段长度,(目录,分析器,重建索引)
IndexWriter.flush()更改为commit();
Hits 命中类 3.0中会被删除。
5、分词方法
字符串匹配的分词方法(正向最大 反向匹配 最小切分 双向匹配)
词义分析(不成熟 LingPipe自然语言处理的Java开源工具包 主题概念分类)、统计分词(分词词典)。
6、lucene索引访问原则
同一时刻,lucene索引中允许有一个进程对其进行加入文档,删除文档,更新索引等操作。
同一时刻,lucene索引允许多个线程同时对其进行检索。
7、Lucene锁机制
使用commit.lock与write.lock实现锁机制。所谓的锁其实是存放于系统临时目录内的一个文件。
建立索引 write.lock / 合并索引 commit.lock segment合并和读取
8、lucene索引文件格式
segment:一个索引中,会包含有多个segment。每个segment都有一个统一的前缀,前缀是当前索引的document数量
segments:一个完整的索引中,有且只有一个“segments”文件,记录了当前索引中所有segment的信息。
.cfs格式:复合索引格式,IndexWriter的属性:useCompoundFile,索引的内容可能非常大,文件数量可能非常的多
.tii和.tis格式:存储分词后的词条,tii是所有文件,标明了每个.tis文件中词条的位置
fnm格式:fnm格式的文件包含了Document中的所有Field名称。
.fdx和.fdt格式:域值存储表,.fdt存储具有Store.YES属性的Field数据
deletable格式:文档被删除后并不是立刻从索引中去除
nrm:标准化因子文件,索引阶段设置Document Boost和Field Boost,对文档评分权重
9、影响Lucene对文档评分权重的四种方式
在索引阶段设置Document Boost和Field Boost,存储在(.nrm)文件中。
在搜索语句中,设置Query Boost.
继承并实现自己的Similarity,实现其中的接口可以干预打分的过程
继承并实现自己的collector 。将docid和score插入一个PriorityQueue中,使得得分最高的文档先返回。
10、lucene增量索引的关键
1、数据库必须对数据是否已经索引做好标识
2、IndexWriter中有一个参数boolean类型的,用来确定是重建索引(true)还是增量索引。