时间 -- ::   CSDN博客   原文  http://blog.csdn.net/caohaicheng/article/details/ 

看lucene主页(http://lucene.apache.org/)上目前lucene已经到4.9.0版本了, 参考学习的书是按照2.1版本讲解的,写的代码例子是用的3.0.2版本的,版本

的不同导致有些方 法的 使用差异,但是大体还是相同的。

源代码用到的jar包(3.0.2版本)下载地址

参考资料:

1、公司内部培训资料

2、《Lucene搜索引擎开发权威经典》于天恩著.

Lucene使用挺简单的,耐心看完都能学会,还有源代码。

一、创建索引的基本方式

所有开源搜索引擎的基本架构和原理都是类似的,Lucene也不例外,用它来建立搜索引擎也是要解决的四个基本问题:抓取数据、解析数据、创建索引和执行搜索。

1、理解创建索引的过程

参考书中对索引的创建有一个很形象的比喻:

创建索引的过程可以类比为写文集。下面以文集的写作为例进行讲解,文集里面有许多文章,每一篇文章包括标题、内容、作品名称、写作时间等信息。

我们采用以下的方式来写这本文集:先写文章,再将文章整合起来。

首先为每一篇文章添加标题、内容、写作时间等信息,从而写好一篇文章。

然后把每一篇文章添加到书里面去,这样文集就写好了。

文集的结构如下图所示:按从左到右的方向,是读文集,即打开一本书,然后翻阅里面的文章;按从右到左的方向是写文集。

创建索引的过程如下:

(1)、建立索引器IndexWriter,这相当于一本书的框架

(2)、建立文档对象Document,这相当于一篇文章

(3)、建立信息字段对象Field,这相当于一篇文章中的不同信息(标题、正文等)。

(4)、将Field添加到Document里面。

(5)、将Document添加到IndexWriter里面。

(6)、关闭索引器IndexWriter。

如下图所示是一个索引的结构,按从左到右是读索引(即搜索)。按从右到左是创建索引:

按照上图所示的结构,创建索引有三个基本的步骤:

(1)、创建Field,将文章的不同信息包装起来

(2)、将多个Field组织到一个Document里面,这样完成了对一篇文章的包装。

(3)、将多个Document组织到一个IndexWriter里面,也就是将多个文章组装起来,最终形成索引

下面的三个小节就按照创建索引的基本步骤来讲解创建索引的具体方法。

2、创建Field

创建Field的方法有许多,下面是最常用的方法。

Field field=new Field(Field名称,Field内容,存储方式,索引方式);

这四个参数的含义如下:

(1)、Field名称就是为Field起的名字,类似于数据表的字段名称。

(2)、Field内容就是该Field的内容,类似数据库表的字段内容。

(3)、存储方式包括三种:不存储(Field.Store.NO)、完全存储(Field.Store.YES)和压缩存储(Field.Store.COMPRESS)。

通常,如果不担心索引太大的话,可以都使用完全存储的方式。但是,出于对性能的考虑,索引文件的内容是越小越好。因此,如果Field的内容很少就采用完全存储(如标

题),如果Field的内容很多就采用不存储或压缩存储的方式,如正文。

(4)、索引的方式包括四种:

不索引(Field.Index.NO)、索引但不分析(Field.Index.NO_NORMS)、索引但不分词(Field.Index.UN_TOKENIZED)、分词并索引(Field.Index.TOKENIZED)。

3、创建Document

创建Document方法如下:

Document doc=new Document();

这个方法用来创建一个不含有任何Field的空Document。

如果想把Field添加到Document里面,只需要add方法。例如doc.add(field);

重复的使用就可以将多个Field加入到一个Document里面。

4、创建IndexWriter

创建IndexWriter方式也不少,拿出一个常用的:

<span style="font-family:SimSun;font-size:12px;"><span style="font-family:SimSun;font-size:12px;">			File indexDir = new File("E:\\Index");
Directory dir = new SimpleFSDirectory(indexDir);
Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_30);
IndexWriter indexWriter = new IndexWriter(dir, analyzer, true, IndexWriter.MaxFieldLength.LIMITED);</span></span>

关于几个参数的介绍:

(1)、Directory (目录类型) 该类是抽象类

它的直接子类在不同版本中还是有区别的,我们直说3.0.2版本,它的子类包括 、 、 FileSwitchDirectory、 CompoundFileReader ,两个子类代表着不同的两种目录类型

FSDirectory:文件系统中的一个路径,会直接将索引写入到磁盘上

RAMDirectory:内存中的一个区域,虚拟机退出后内容会随之消失,所以需要将RAMDirectory中的内容转到FSDirectory。

FileSwitchDirectory: 一个是用于可以同时在两个不同的目录中读取文件的FileSwitchDirectory,这是个代理类。

CompoundFileReader: 是用户读取复合文件的CompoundFileReader,只能读取扩展名为cfs的文件。(写扩展名为cfs的文件用CompoundFileWriter)CompoundFileReader仅在SegmentReader中被引用。

其中FSDirectory又分为3类:

A、 windows下的SimpleFSDirectory

B、linux支持NIO的NIOFSDirectory

C、还有一个是内存Map目录MMapDirectory

(2)、Analyzer(分析器) 抽象类

负责对各种输入的数据源进行分析,包括过滤和分词等多种功能。

分析器是用来做词法分析的,包括英文分析器和中文分析器等。要根据所要建立的索引的文件情况选择合适的分析器。常用的有StandardAnalyzer(标准分析器)、CJKAnalyzer(二分法分词

器)、ChineseAnalyzer(中文分析器)等。

可以根据自己的需要去编辑分析器,从而处理不同 的语言文字(当然,我不会)。

IndexWriter创建完之后可以用addDocument()的方法将document对象放置到IndexWriter中:writer.addDocument(doc);

可以放置多个。

最终要调用close()方法关闭索引器,例如writer.close();

到此,创建索引的步骤就介绍完了,下面我们就该看实例了:

二、创建一个简单索引实例:

<span style="font-family:SimSun;font-size:12px;">import java.io.File;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.SimpleFSDirectory;
import org.apache.lucene.util.Version; public class LuceneMainProcess { public static void main(String[] args) {
createLuceneIndex();
} public static void createLuceneIndex() {
try {
File indexDir = new File("E:\\Index");
Directory dir = new SimpleFSDirectory(indexDir);
Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_30);
//IndexWriter为某个Document建立索引时所取到的Field内的最大词条数目,该属性的初始值为10000
IndexWriter indexWriter = new IndexWriter(dir, analyzer, true, IndexWriter.MaxFieldLength.LIMITED);
// 创建8个文档
Document doc1 = new Document();
Document doc2 = new Document();
Document doc3 = new Document();
Document doc4 = new Document();
Document doc5 = new Document();
Document doc6 = new Document();
Document doc7 = new Document();
Document doc8 = new Document(); Field f1 = new Field("bookname", "钢铁是怎样炼成的", Field.Store.YES,
Field.Index.ANALYZED);
Field f2 = new Field("bookname", "英雄儿女", Field.Store.YES,
Field.Index.ANALYZED);
Field f3 = new Field("bookname", "篱笆女人和狗", Field.Store.YES,
Field.Index.ANALYZED);
Field f4 = new Field("bookname", "女人是水做的", Field.Store.YES,
Field.Index.ANALYZED);
Field f5 = new Field("bookname", "我的兄弟和女儿", Field.Store.YES,
Field.Index.ANALYZED);
Field f6 = new Field("bookname", "白毛女", Field.Store.YES,
Field.Index.ANALYZED);
Field f7 = new Field("bookname", "钢的世界", Field.Store.YES,
Field.Index.ANALYZED);
Field f8 = new Field("bookname", "钢铁战士", Field.Store.YES,
Field.Index.ANALYZED); doc1.add(f1);
doc2.add(f2);
doc3.add(f3);
doc4.add(f4);
doc5.add(f5);
doc6.add(f6);
doc7.add(f7);
doc8.add(f8); indexWriter.addDocument(doc1);
indexWriter.addDocument(doc2);
indexWriter.addDocument(doc3);
indexWriter.addDocument(doc4);
indexWriter.addDocument(doc5);
indexWriter.addDocument(doc6);
indexWriter.addDocument(doc7);
indexWriter.addDocument(doc8); indexWriter.optimize();//对索引进行优化,保证检索时的速度,但是需要消耗内存和磁盘空间,耗时耗力,需要的时候再优化(而非任意时刻)
indexWriter.close();//关闭索引器,否则会导致索引的数据滞留在缓存中未写入磁盘,有可能连目录的锁也没有去除
} catch (Exception e) {
e.printStackTrace();
}
} }
</span>

执行之后我们发现E盘下出现了一个index目录,这就是我们创建的索引文件。

到此,索引文件也就是创建完毕了。

明天接着往下整理索引的读取,到时候我们就可以更直观的判断上面创建的索引是否成功。

lucene 建立索引的过程的更多相关文章

  1. lucene建立索引的过程

    建立索引过程 用户提交数据=>solr建立索引=>调用lucene包建立索引 官方建立索引和查询索引的例子如下: http://lucene.apache.org/core/4_10_3/ ...

  2. Lucene建立索引搜索入门实例

                                第一部分:Lucene建立索引 Lucene建立索引主要有以下两步:第一步:建立索引器第二步:添加索引文件准备在f盘建立lucene文件夹,然后 ...

  3. 【转】Lucene不同版本中Field的Keyword、UnIndex,导致lucene 建立索引总是报错 急!!

    lucene 建立索引 总是报错 急!! http://zhidao.baidu.com/link?url=iaVs9JH4DfN6iwaWImt7VMJENWCWGGaWFGPjqhUw_jz7Fs ...

  4. Lucene4.9学习笔记——Lucene建立索引

    基本上创建索引需要三个步骤: 1.创建索引库IndexWriter对象 2.根据文件创建文档Document 3.向索引库中写入文档内容 这其中主要涉及到了IndexWriter(索引的核心组件,用于 ...

  5. elasticsearch(lucene)索引数据过程

    倒排索引存储-分段存储(lucene的功能)在lucene中:lucene index包含了若干个segment在elasticsearch中:index包含了若干主从shard,shard包干了若干 ...

  6. lucene 建立索引的不同方式

    1.创建一个简单的索引: package lia.meetlucene; import java.io.File; import org.apache.lucene.document.Document ...

  7. solr建立索引的过程

    HttpSolrServer HttpSolrServer继承SolrServer 参考文档:http://my.oschina.net/qige/blog/173008

  8. html抽取文本信息-java版(适合lucene建立索引)

    import org.htmlparser.NodeFilter; import org.htmlparser.Parser; import org.htmlparser.beans.StringBe ...

  9. 利用Lucene将被索引文件目录中的所有文件建立索引

    1.新建两个文件夹htm和index,其中htm中存放被索引的文件,index文件中存放建立的索引文件. 2.新建解析目录中所有文件的类,用来解析指定目录下的所有文件. import java.io. ...

随机推荐

  1. javascript动态添加form表单元素

    2014年11月7日 17:10:40 之前写过几篇类似的文章,现在看来比较初级,弄一个高级的简单的 情景: 后台要上传游戏截图,截图数量不确定,因此使用动态添加input节点的方法去实现这个效果 主 ...

  2. ffplay 2.5.3 媒体播放器

    下载地址 http://pan.baidu.com/s/1bnlMYB1 一定要解压到 D:\ffmpeg\ 目录下 双击 OpenWith_FFPlay.reg 注册ffplay 在视频文件名上面, ...

  3. Java for LeetCode 052 N-Queens II

    Follow up for N-Queens problem. Now, instead outputting board configurations, return the total numbe ...

  4. oracle的关闭过程(各个模式关闭)

    关闭数据库与实例 与数据库启动一下,关闭数据库与实例也分为3步:关闭数据库-->实例卸载数据库--->终止实例. 1.Nomal(正常关闭方式) 命令:shutdown nomal 讲解: ...

  5. Java Serializable(序列化)

    1.序列化是干什么的? 简单说就是为了保存在内存中的各种对象的状态(也就是实例变量,不是方法),并且可以把保存的对象状态再读出来.虽然你可以用你自己的各种各样的方法来保存object states,但 ...

  6. 【HTML5】Server-Sent服务器发送事件

    Server-Sent 事件 - 单向消息传递 Server-Sent 事件指的是网页自动获取来自服务器的更新. 以前也可能做到这一点,前提是网页不得不询问是否有可用的更新.通过服务器发送事件,更新能 ...

  7. loadrunner个版本历程

    1.工具介绍: LoadRunner是一种预测系统行为和性能的负载测试工具.通过以模拟上千万用户实施并发负载及实时性能监测的方式来确认和查找问题, LoadRunner能够对整个企业架构进行测试.通过 ...

  8. 关于post和get传递参数的区别

    今天一朋友给我一段代码,说使用request.querystrin得不到传过来的值,我们一起找到很长时间,终于给找到了,错误的原因是他将form中的method参数写成了get了,所以使用reques ...

  9. 2016.6.17 kali Linux 隧道工具

    隧道工具的基本概念: 1.在计算机网络中,隧道工具是指使用一种网络协议去封装另一种网络协议的技术. 2.通常用来数据伪装或者穿越防火墙,在入侵目标系统后,可用来提升权限和权限维持. Kali中的隧道工 ...

  10. C#线程间同步无法关闭

    用C#做了个线程间同步的小程序,但每次关闭窗口后进程仍然在,是什么原因? 解决方法: 要加一句 线程.IsBackground = true; 否则退出的只是窗体 上面的方法没看懂... MSDN上说 ...