JAVAlucene全文检索工具包的理解与使用

上传人:宝路 文档编号:20891339 上传时间:2017-11-22 格式:DOC 页数:12 大小:53.12KB
返回 下载 相关 举报
JAVAlucene全文检索工具包的理解与使用_第1页
第1页 / 共12页
JAVAlucene全文检索工具包的理解与使用_第2页
第2页 / 共12页
JAVAlucene全文检索工具包的理解与使用_第3页
第3页 / 共12页
JAVAlucene全文检索工具包的理解与使用_第4页
第4页 / 共12页
JAVAlucene全文检索工具包的理解与使用_第5页
第5页 / 共12页
点击查看更多>>
资源描述

《JAVAlucene全文检索工具包的理解与使用》由会员分享,可在线阅读,更多相关《JAVAlucene全文检索工具包的理解与使用(12页珍藏版)》请在金锄头文库上搜索。

1、申明:原文来自 http:/ lucene 简介 1.1 什么是 luceneLucene 是一个全文搜索框架,而不是应用产品。因此它并不像 或者 google Desktop 那么拿来就能用,它只是提供了一种工具让你能实现这些产品。 1.2 lucene 能做什么 要 回答这个问题,先要了解 lucene 的本质。实际上 lucene 的功能很单一,说到底,就是你给它若干个字符串,然后它为你提供一个全文搜索服务,告诉你 你要搜索的关键词出现在哪里。知道了这个本质,你就可以发挥想象做任何符合这个条件的事情了。你可以把站内新闻都索引了,做个资料库;你可以把一个数据库 表的若干个字段索引起来,那

2、就不用再担心因为“%like%”而锁表了;你也可以写个自己的搜索引擎 1.3 你该不该选择 lucene下面给出一些测试数据,如果你觉得可以接受,那么可以选择。 测试一:250 万记录,300M 左右文本,生成索引 380M 左右,800 线程下平均处理时间300ms。 测试二:37000 记录,索引数据库中的两个 varchar 字段,索引文件 2.6M,800 线程下平均处理时间 1.5ms。 2 lucene 的工作方式lucene 提供的服务实际包含两部分:一入一出。所谓入是写入,即将你提供的源(本质是字符串)写入索引或者将其从索引中删除;所谓出是读出,即向用户提供全文搜索服务,让用户

3、可以通过关键词定位源。 2.1 写入流程源字符串首先经过 analyzer 处理,包括:分词,分成一个个单词;去除 stopword(可选) 。 将源中需要的信息加入 Document 的各个 Field 中,并把需要索引的 Field 索引起来,把需要存储的 Field 存储起来。 将索引写入存储器,存储器可以是内存或磁盘。 2.2 读出流程 用户提供搜索关键词,经过 analyzer 处理。 对处理后的关键词搜索索引找出对应的 Document。 用户根据需要从找到的 Document 中提取需要的 Field。 3 一些需要知道的概念lucene 用到一些概念,了解它们的含义,有利于下面

4、的讲解。 3.1 analyzerAnalyzer 是分析器,它的作用是把一个字符串按某种规则划分成一个个词语,并去除其中的无效词语,这里说的无效词语是指英文中的“of”、 “the”,中文中的 “的”、 “地”等词语,这些词语在文章中大量出现,但是本身不包含什么关键信息,去掉有利于缩小索引文件、提高效率、提高命中率。 分词的规则千变万化,但目的只有一个:按语义划分。这点在英文中比较容易实现,因为英文本身就是以单词为单位的,已经用空格分开;而中文则必须以某种方法将连成一片的句子划分成一个个词语。具体划分方法下面再详细介绍,这里只需了解分析器的概念即可。3.2 document用户提供的源是一条

5、条记录,它们可以是文本文件、字符串或者数据库表的一条记录等等。一条记录经过索引之后,就是以一个 Document 的形式存储在索引文件中的。用户进行搜索,也是以 Document 列表的形式返回。 3.3 field一个 Document 可以包含多个信息域,例如一篇文章可以包含“标题”、 “正文”、 “最后修改时间”等信息域,这些信息域就是通过 Field 在 Document 中存储的。 Field 有两个属性可选:存储和索引。通过存储属性你可以控制是否对这个 Field 进行存储;通过索引属性你可以控制是否对该 Field 进行索引。这看起来似乎有些废话,事实上对这两个属性的正确组合很重

6、要,下面举例说明: 还 是以刚才的文章为例子,我们需要对标题和正文进行全文搜索,所以我们要把索引属性设置为真,同时我们希望能直接从搜索结果中提取文章标题,所以我们把标题 域的存储属性设置为真,但是由于正文域太大了,我们为了缩小索引文件大小,将正文域的存储属性设置为假,当需要时再直接读取文件;我们只是希望能从搜索解 果中提取最后修改时间,不需要对它进行搜索,所以我们把最后修改时间域的存储属性设置为真,索引属性设置为假。上面的三个域涵盖了两个属性的三种组合,还 有一种全为假的没有用到,事实上Field 不允许你那么设置,因为既不存储又不索引的域是没有意义的。 3.4 termterm 是搜索的最小

7、单位,它表示文档的一个词语,term 由两部分组成:它表示的词语和这个词语所出现的 field。 3.5 tockentocken 是 term 的一次出现,它包含 trem 文本和相应的起止偏移,以及一个类型字符串。一句话中可以出现多次相同的词语,它们都用同一个 term 表示,但是用不同的 tocken,每个 tocken 标记该词语出现的地方。 3.6 segment添加索引时并不是每个 document 都马上添加到同一个索引文件,它们首先被写入到不同的小文件,然后再合并成一个大索引文件,这里每个小文件都是一个 segment。 4 lucene 的结构 lucene 包括 core

8、和 sandbox 两部分,其中 core 是 lucene 稳定的核心部分,sandbox 包含了一些附加功能,例如 highlighter、各种分析器。 Lucene core 有七个包: analysis,document ,index ,queryParser ,search,store,util 。 4.1 analysisAnalysis 包含一些内建的分析器,例如按空白字符分词的 WhitespaceAnalyzer,添加了stopwrod 过滤的 StopAnalyzer,最常用的 StandardAnalyzer。 4.2 documentDocument 包含文档的数据结构

9、,例如 Document 类定义了存储文档的数据结构,Field 类定义了 Document 的一个域。 4.3 indexIndex 包含了索引的读写类,例如对索引文件的 segment 进行写、合并、优化的IndexWriter 类和对索引进行读取和删除操作的 IndexReader 类,这里要注意的是不要被IndexReader 这个名字误导,以为它是索引文件的读取类,实际上删除索引也是由它完成, IndexWriter 只关心如何将索引写入一个个 segment,并将它们合并优化; IndexReader 则关注索引文件中各个文档的组织形式。 4.4 queryParserQueryP

10、arser 包含了解析查询语句的类,lucene 的查询语句和 sql 语句有点类似,有各种保留字,按照一定的语法可以组成各种查询。 Lucene 有很多种 Query 类,它们都继承自Query,执行各种特殊的查询,QueryParser 的作用就是解析查询语句,按顺序调用各种 Query 类查找出结果。 4.5 searchSearch 包含了从索引中搜索结果的各种类,例如刚才说的各种 Query 类,包括TermQuery、BooleanQuery 等就在这个包里。 4.6 store Store 包含了索引的存储类,例如 Directory 定义了索引文件的存储结构, FSDirect

11、ory 为存储在文件中的索引,RAMDirectory 为存储在内存中的索引,MmapDirectory 为使用内存映射的索引。 4.7 utilUtil 包含一些公共工具类,例如时间和字符串之间的转换工具。 5 如何建索引5.1 最简单的能完成索引的代码片断IndexWriter writer = new IndexWriter(“/data/index/”, new StandardAnalyzer(), true); Document doc = new Document(); doc.add(new Field(title, lucene introduction, Field.Sto

12、re.YES, Field.Index.TOKENIZED); doc.add(new Field(content, lucene works well, Field.Store.YES, Field.Index.TOKENIZED); writer.addDocument(doc); writer.optimize(); writer.close(); 下面我们分析一下这段代码。 首先我们创建了一个 writer,并指定存放索引的目录为“/data/index”,使用的分析器为StandardAnalyzer,第三个参数说明如果已经有索引文件在索引目录下,我们将覆盖它们。 然后我们新建一个

13、document。 我们向 document 添加一个 field,名字是“title” ,内容是“lucene introduction”,对它进行存储并索引。 再添加一个名字是“content”的 field,内容是“lucene works well”,也是存储并索引。 然后我们将这个文档添加到索引中,如果有多个文档,可以重复上面的操作,创建document 并添加。 添加完所有 document,我们对索引进行优化,优化主要是将多个 segment 合并到一个,有利于提高索引速度。 随后将 writer 关闭,这点很重要。 对,创建索引就这么简单! 当然你可能修改上面的代码获得更具个性

14、化的服务。 5.2 将索引直接写在内存 你需要首先创建一个 RAMDirectory,并将其传给 writer,代码如下: Directory dir = new RAMDirectory(); IndexWriter writer = new IndexWriter(dir, new StandardAnalyzer(), true); Document doc = new Document(); doc.add(new Field(title, lucene introduction, Field.Store.YES, Field.Index.TOKENIZED); doc.add(new

15、 Field(content, lucene works well, Field.Store.YES, Field.Index.TOKENIZED); writer.addDocument(doc); writer.optimize(); writer.close(); 5.3 索引文本文件 如果你想把纯文本文件索引起来,而不想自己将它们读入字符串创建 field,你可以用下面的代码创建 field: Field field = new Field(content, new FileReader(file); 这里的 file 就是该文本文件。该构造函数实际上是读去文件内容,并对其进行索引,但

16、不存储。 6 如何维护索引索引的维护操作都是由 IndexReader 类提供。 6.1 如何删除索引lucene 提供了两种从索引中删除 document 的方法,一种是 void deleteDocument(int docNum) 这种方法是根据 document 在索引中的编号来删除,每个 document 加进索引后都会有个唯一编号,所以根据编号删除是一种精确删除,但是这个编号是索引的内部结构,一般我们不会知道某个文件的编号到底是几,所以用处不大。另一种是 void deleteDocuments(Term term) 这种方法实际上是首先根据参数 term 执行一个搜索操作,然后把搜索到的结果批量删除了。我们可以通过这个方法提供一个严格的查询条件,达到删除指定 document 的目的。 下面给出一个例子: Directory dir = FSDirectory.g

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 办公文档 > 其它办公文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号