Lucene4.9学习笔记——Lucene建立索引
基本上创建索引需要三个步骤:
1、创建索引库IndexWriter对象
2、根据文件创建文档Document
3、向索引库中写入文档内容
这其中主要涉及到了IndexWriter(索引的核心组件,用于创建或追加索引)、Document(代表一些域Field的集合)、Field(具体的域,如文档创建时间、作者、内容等)、Analyzer(分词器)、Directory(用于描述索引存放位置)这些主要的类。
我们参照上一节的代码来看建立索引。
1、创建IndexWriter
// 索引文件的保存位置 |
这里先是定义存放索引文件的位置,然后定义分析器(分词器),我这里没有使用昨天提到的一个官方的smartcn那个jar的分词器,自己试了一下,发现不是很好用,居然是搜索失败的。不过中文的话,应该还是IK Analyzer比较好吧。
StandardAnalyzer是 lucene 中内置的“标准分析器”,可以做如下功能:
l 对原有句子按照空格进行了分词
l 所有的大写字母都可以能转换为小写的字母
l 可以去掉一些没有用处的单词,例如”is”,”the”,”are”等单词,也删除了所有的标点
当然这里也可以一些其他的分词器,Lucene中也自带了中文的分词器,是lucene-analyzers-smartcn.Jar中的SmartChineseAnalyzer,但是我用了一下发现对中文的处理并不好。
当然其他的中文分词器还有很流行的IKAnalyzer,这个一定要用FF的版本,意思是for four才是给我们4.x用的。
在下面是定义配置类,这里有个setOpenMode,有下面几个选项:
APPEND:总是追加,可能会导致错误,索引还会重复,导致返回多次结果
CREATE:清空重建(推荐)
CREATE_OR_APPEND【默认】:创建或追加
这里还是建议先用CREATE吧,当然学习的深入了之后使用CREATE_OR_APPEND可能会让索引创建效率更高。
另外,IndexWriter的创建也是相当耗费资源的,所以如有可能,尽量使用单例(注意线程 安全 )。
2、根据数据创建文档
首先说下Field、Document、索引之间的关系,简单一句话:多个Field组成一个Document,多个Document组成一个索引。
在创建索引的过程中比较重要的就是创建不同的Field,看看api就可以知道Field有哪些实现:BinaryDocValuesField, DoubleField, FloatField, IntField, LongField, NumericDocValuesField, SortedDocValuesField, SortedNumericDocValuesField, SortedSetDocValuesField, StoredField, StringField, TextField。
比较常用的有LongField、StoredField、StringField、TextField。具体有哪些构造方法建议大家自己查阅api文档。
每种Field都有具体的介绍,我这里重点介绍一下常用的几个:
LongField:索引但是不分词,适用于全部搜索,一般用于文件创建、修改时间的秒数等。
StoredField:只存不索引
StringField:索引但是不分词,所以适用于全部搜索的内容,比如国家等,要么不对,要么就是全对。另外提一句,这个有个长度限制是32766,大家使用的时候自己斟酌一下,一般不会超过。
TextField:索引并分词,所以这个应该是我们做 全文检索 的时候应该最常用到的一个Field。
Document doc = new Document(); |
这样首先声明一个Document,然后声明一系列Field,然后添加字段即可。
这里有个重点就是Field,其实也比较简单。在4.x以前是没有各种各样的Field的,都是通过传参,现在就已经有了不同的实现,可以按需选择了。
StringField即为NOT_ANALYZED的(即不对域的内容进行分割分析),而TextField是ANALYZED的,因此,创建Field对象时,无需再指定分析类型了。
下面是官方描述:
StringField: A field that is indexed but not tokenized
TextField: A field that is indexed and tokenized
下面介绍一些有关Field的相关选项
a. Field.Store.Yes/No
在创建Field的时候,需要传入一个参数,来指定内容是否需要存储到索引中。这些被存储的内容可以在搜索结果中返回,用于展现显示,即使用document.get(“name”)时,是否可以直接返回内容。
一般文件的作者、创建时间、文件名等信息可以存储,但是内容就没必要存储了,一方面是内容太多太大,另一方面也是因为我们的程序可以引导用户直接访问原文件查看即可。
b.加权(后面会细说)
可以对Filed及Document进行加权。注意加权是影响返回结果顺序的一个因素,但也仅仅是一个因素,它和其它因素一起构成了Lucene的排序 算法 。
下面继续介绍一个对富文本(非纯文本)索引的方法。
对于word,excel,pdf等富文本,FileReader读取到的会是 乱码 ,无法有效的索引。这时候可以使用Tika等工具先将其正文内容提取出来,然后再进行索引。
使用Tika进行正文提取的方法见我的github:
https://github.com/irfen/lucene-example/blob/master/src/test/java/me/irfen/lucene/ch03/TikaTest.java
更多Tika内容以后如果有时间会详细介绍。这里我使用的是Tika1.5版本,他依赖的包有点多,使用maven进行构建只需要如下两个配置即可:
<dependency> |
3、向索引库中写入文档内容
这一步很简单,直接就是writer.addDocument(doc);就可以了。
这里简单介绍下对索引的优化,索引过程中,会将索引结果放到多个索引文件中,这样会回收索引的效率,但在搜索时,需要将多个索引文件中的返回结果并进行合并处理,因此效率较低。
在添加文档之后执行writer.forceMerge(2);,索引的优化是将索引结果文件归为一个或者有限的多个,它加大索引过程中的耗时(降低了效率),减少了搜索时的耗时(提高了效率)。
4、关于Directory
目前用的比较多的有两个Directory,一个是FSDirectory,一个是RAMDirectory。
看一眼FSDirectory的源码,会发现下面这段:
public static FSDirectory open(File path, LockFactory lockFactory) throws IOException {
|
其实FSDirectory是根据不同的操作系统和JRE返回不同的Directory。
而另一个常用的是RAMDirectory,这个是内存索引,只对小索引好用,大量索引会导致频繁GC。
另外介绍一下FileSwitchDirectory,这是一个基于文件目录切换的一个实现。有时候我们想要同时获得两个Directory的优点,这就是FileSwitchDirectory的作用。下面是他的构造方法:
public FileSwitchDirectory(Set primaryExtensions, Directory primaryDir, Directory secondaryDir, boolean doClose) {
|
这里可以看到他要两个Directory,通过第一个参数我们可以指定主索引需要加载的索引文件,其它的将会由从Directory来实现,由此达到快速切换不同的Directory来使用他们各自的优点。
Lucene4.9学习笔记——Lucene建立索引的更多相关文章
- SQL反模式学习笔记4 建立主键规范【需要ID】
目标:建立主键规范 反模式:每个数据库中的表都需要一个伪主键Id 在表中,需要引入一个对于表的域模型无意义的新列来存储一个伪值,这一列被用作这张表的主键, 从而通过它来确定表中的一条记录,即便其他的列 ...
- SQL反模式学习笔记13 使用索引
目标:优化性能 改善性能最好的技术就是在数据库中合理地使用索引. 索引也是数据结构,它能使数据库将指定列中的某个值快速定位在相应的行. 反模式:无规划的使用索引 1.不使用索引或索引不足 2.使用了 ...
- Mysql数据库学习笔记之数据库索引(index)
什么是索引: SQL索引有两种,聚集索引和非聚集索引,索引主要目的是提高了SQL Server系统的性能,加快数据的查询速度与减少系统的响应时间. 聚集索引:该索引中键值的逻辑顺序决定了表中相应行的物 ...
- Lucene建立索引搜索入门实例
第一部分:Lucene建立索引 Lucene建立索引主要有以下两步:第一步:建立索引器第二步:添加索引文件准备在f盘建立lucene文件夹,然后 ...
- 【转】Lucene不同版本中Field的Keyword、UnIndex,导致lucene 建立索引总是报错 急!!
lucene 建立索引 总是报错 急!! http://zhidao.baidu.com/link?url=iaVs9JH4DfN6iwaWImt7VMJENWCWGGaWFGPjqhUw_jz7Fs ...
- python学习笔记:建立一个自己的搜索引擎
写学习笔记是我学习python以来养成的一个习惯,每学习一个知识点,便整理成文字记录下来.搜索引擎大家经常都有在使用,国内外也很很多搜索引擎平台. Google搜索引擎建立至今已经快20年了,之后全球 ...
- lucene 建立索引的过程
时间 -- :: CSDN博客 原文 http://blog.csdn.net/caohaicheng/article/details/ 看lucene主页(http://lucene.apach ...
- 用Lucene4.5对中文文本建立索引
这里需要完成一个能对txt文本建立索引,并能完成检索查询.完成这个功能,使用的是Lucene4.5,同时使用其自带的中文分析器. 准备工作是在一个文件夹里面建一些txt文件,这是我的文件结构: 首先要 ...
- lucene建立索引的过程
建立索引过程 用户提交数据=>solr建立索引=>调用lucene包建立索引 官方建立索引和查询索引的例子如下: http://lucene.apache.org/core/4_10_3/ ...
随机推荐
- HTML中Select的使用具体解释
<html> <head> <SCRIPT LANGUAGE="JavaScript"> <!-- //oSelect 列表的底部加入了一 ...
- matlab两种不同模式的并行运算
1.distributed job distributed job是一种比較简单的并行任务.假定用户须要完毕一组作业.各个计算作业之间是独立的.并且相互之间不须要进行数据通信.这意味着各个作 ...
- Ajax之旅(一)--什么是Ajax
本来在学习DRP,但是无意中发现所附资料中有一些參考书籍,当中就有一个关于Ajax的,看了看,挺好的,于是决定暂停一下DRP,再次学习一下Ajax.记得第一遍学习Ajax的时候认为真的是一团雾水,看了 ...
- Match+Faq
假如在GameLayer.h中有Card类型的变量,那么在Card.h文件中,不要有GameLayer.h的导入.这样子会导致编译器找不到对Card类型的定义而导致报错.但是,在Card.cpp中可以 ...
- AIR lame参数配置
-Duser.name=Z.yu 固定码率的例子:=======================================================================固定码率 ...
- iOS多线程开发--NSThread NSOperation GCD
多线程 当用户播放音频.下载资源.进行图像处理时往往希望做这些事情的时候其他操作不会被中 断或者希望这些操作过程中更加顺畅.在单线程中一个线程只能做一件事情,一件事情处理不完另一件事就不能开始,这样势 ...
- (转)了解了这些才能开始发挥jQuery的威力
原文地址:http://www.cnblogs.com/dolphinX/p/3347677.html 由于当前jQuery如此的如雷贯耳,相信不用介绍什么是jQuery了,公司代码中广泛应用了jQu ...
- ACM——线性表操作
线性表操作 时间限制(普通/Java):1000MS/3000MS 运行内存限制:65536KByte总提交:2795 测试通过:589 描述 线性表是n个元素 ...
- sql server 的JDBC 配置
1.java中使用数据库需要用JDBC(java database connection)来连接和操作 下载地址:http://www.microsoft.com/en-us/download/det ...
- WPFX名称空间
1:x名称空间里的成员是专门写给xaml编译器看,用来引导xaml编译器把xaml代码编译成CLR代码的.(x仅仅是xaml的首字母). 2:attribute 是语言层面的东西,是给编译器看的,Pr ...