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/ ...
随机推荐
- 有关UIImageView+AFNetworking 下载图片的线程问题
今天写了一个demo,从服务器获取图片,然后显示在cell上,大家都知道cell的重用机制,当往下拉的时候,上面的cell遮住了,下面的cell就会重用被遮住的cell, 贴代码: NSString ...
- contentProvider模板
package com.example.qunzheng.todolist.provider; import android.content.ContentProvider; import andro ...
- gulp 实践
文档站YDoc 相关注意事项 sass 编译 目录结构 可以直接使用sass编译 ➜ ydoc git:(v2) ✗ sass ./sass/app.scss ./template/source/ap ...
- redhat 6.4 双网卡绑定
linux系统配置 1.redhat 6.4 双网卡绑定 1)#ethtool eth* //在服务器网口接网线至笔记本,确定各网口的配置文件: 2)切换目录 #cd /etc/sysconfig/n ...
- case when then 与 count联合使用
我们都知道SQL中适用case when then来转化数据库中的信息 比如 select (case sex when 0 then '男' else '女' end) AS sex from ...
- dsoframer控件在64系统上使用问题小汇总
由于工作中需要,我接触了dsoframer控件,我办公电脑是64系统,在使用时,总是报没有注册类错误.我很是奇怪,dsoframer.ocx控件我都注册过的呀.然后在网上查阅了许多相关资料.悲哀的是, ...
- DataContext 数据在F5刷新频繁,会出现数据读取错误
DataContext 数据在F5刷新频繁,会出现数据读取错误 DataContext是 Linq to sql数据模型的底层数据库对象所有LInq数据表对象都是由它派生的, 只要建立一个数据库操作, ...
- 1_使用Java文件的并发写
为了实现,并发写操作,首先实验一下在本地情况下, 将一个文件切分成若干个 文件块 然后将文件块 通过多线程的并发的方式写入到指定目录下的文件中. 下面是简单的试着实现代码,暂时 先进行记录一下: im ...
- SQL SERVER语句汇总
1.查询数据库中所有用户表名:用户表总数. select name from dbo.sysobjects where OBJECTPROPERTY(id,N'IsUserTable')=1 sele ...
- ubuntu 安装 fcitx
安装fcitx (1)添加ppa源 sudo add-apt-repository ppa:fcitx-team/nightly 或 sudo add-apt-repository ppa:fcitx ...