`

全文检索引擎Lucene

阅读更多

全文检索引擎Lucene

1.       信息检索的概念

从信息集合中找出与用户需求相关的信息。被检索的信息包括文本、图像、音频、视频等多媒体信息。

2.       信息检索的分类

全文检索:把用户的查询请求和全文的每一个词进行比较,不考虑查询请求与文本语义上的匹配。在信息检索工具中,全文检索是最具通用性和实用性的。(只搜索文本

数据检索

知识检索

3.       全文检索流程

 

*从信息源中拷贝到本地进行加工,生成的信息集合称为索引表,搜索时从本地的信息集合中搜索

*文本在建立索引和搜索时都会先分词(使用分词器),且使用同一个分词器,不同的语言有不同的分词器

 

全文检索与数据库查询的比较

1.匹配效果:如搜索ant,在sql中用like %ant% 会搜出planting 但它不应该出现

2.查出的结果没有相关度排序,不知道有用的结果在哪一页。

3.搜索速度慢,达不到毫秒级的要求

 

Lucene介绍与初步使用

Lucene是一个高性能、可伸缩的全文检索工具包。可以使用它为你的应用程序添加索引和搜索功能。

Lucene的作者Doug Cutting 是资深的全文检索专家。最初,Lucene以开源的形式出现在SourceForget上。2001Lucene加入了Apache旗下的Jakarta项目。2005年,Lucene正式脱离Jakarta成为Apache旗下的顶级项目。现在,Lucene的主页为http://lucene.apache.org/

目前有很多应用程序使用Lucene来提供全文检索的功能,如Eclipse的帮助子系统就是使用Lucene实现的。

 

 

Lucene中对应的类

Directory:索引库的位置,一般为一个目录

Document:信息集合中的每条数据。是field的集合

Field:是感兴趣的内容.

f1 = new Field(title,xxxx);//值为文本,如日期,数字要转型

f2 = new Field(body,xxxx);

doc.add(f1);

doc.add(f2);

 

Analyzer:分词器

IndexWriter:用来操作索引库的(增、删、改)

IndexSearcher:是用来在索引库中进行查询的

Query:查询对象,解析查询条件

 

分词器

分词器,对文本资源进行切分,将文本按规则切分为一个个可以进行索引的最小单位(关键词)

 

英文分词

分词流程:

输入文本à关键字切分à去除停用词à形态还原à转为小写

停用词:对文本所携带的信息基本不产生影响的词。如英文的“a, an,of,the”,中文的“的,了,着”。

例:对“IndexWriter  addDocuments  a  javadoc.txt”进行分词

1,切分词

IndexWriter    addDocuments    a    javadoc.txt

2,去除停用词

IndexWriter    addDocuments     javadoc.txt

3,形态还原

IndexWriter    addDocument   javadoc.txt

4,转为小写

indexwriter    adddocument   javadoc.txt

 

中文分词

中文分词比较复杂,如“帽子和服装”。对于中文分词,通常有3种方式:单字分词(StandarAnalyzer)、二分法分词(CJKAnalyzer)、词典分词(MMAnalyzer

例:net.hlj.lucene.analyzer.AnalyzerTest.java

 

下面写一个简单的 索引,检索程序  net.hlj.lucene.test.Test1.java

用到的jar包:

lucene-core-2.4.0.jar

lucene-analyzers-2.4.0.jar

je-analysis-1.5.3.jar

lucene-highlighter-2.4.0.jar

下载地址:http://archive.apache.org/dist/lucene/java/

 

IndexDao

完成对索引的增删改查

 

 

工具类DateToolsNumberTools

 

DateTools:转换日期的工具类,Resolution参数可以指定日期的精度。

NumberTools:转换数字的工具类,把数字转换为36进制的字符串

 

Highligher:高亮器

 

指定要高亮信息的前缀和后缀

 

查询:net.hlj.lucene.query.QueryTest.java

TermQuery:关键词查询

RangeQuery:范围查询

WildcardQuery:通配符查询

PhraseQuery:短语查询

BooleanQuery:布尔查询

 

排序

1相关度排序

Documentboost属性:Document.setBoost(float boost)

Fieldboost属性:Field.setBoost(float boost)

查询时指定:MultFieldQueryParser(String[] fields,Analyzer analyzer,Map boosts)

2按指定字段排序

Public Sort(SortField field)

Public Sort(SortField[] fields)

 

过滤器

RangeFilter ,可以对搜索出来的结果进行过滤

 

 

性能优化

从优化创建索引性能和优化搜索性能两方面介绍

 

优化创建索引性能

IndexWriter提供了一些接口可以控制建立索引的操作,另外我们可以先将索引写入RAMDirectory,再批量写入FSDirectory,不管怎样,目的都是尽量少的文件IO,因为创建索引的最大瓶颈在于磁盘IO。另外选择一个较好的分析器也能提高一些性能。

 

通过设置IndexWriter的参数优化索引建立

setMaxBufferedDocs(int maxBufferedDocs)
控制写入一个新的segment前内存中保存的document的数目,设置较大的数目可以加快建索引速度,默认为10

setMaxMergeDocs(int maxMergeDocs)
控制一个segment中可以保存的最大document数目,值较小有利于追加索引的速度,默认Integer.MAX_VALUE,无需修改。
setMergeFactor(int mergeFactor)
控制多个segment合并的频率,值较大时建立索引速度较快,默认是10,可以在建立索引时设置为100

 

通过RAMDirectory缓写提高性能

我们可以先把索引写入RAMDirectory,达到一定数量时再批量写进FSDirectory,减少磁盘IO次数。     

 

FSDirectory fsDir = FSDirectory.getDirectory("/data/index", true);
RAMDirectory ramDir 
= new 
RAMDirectory();
IndexWriter fsWriter 
= new 
IndexWriter(fsDir, new StandardAnalyzer(), true);
IndexWriter ramWriter 
= new IndexWriter(ramDir, new StandardAnalyzer(), true);

Int i=0;
while (there are documents to index)
{
... create Document ...
ramWriter.addDocument(doc);
if (i==100)
{
fsWriter.addIndexes(new Directory[] { ramDir });
ramWriter.close();
ramWriter = new 
IndexWriter(ramDir, new StandardAnalyzer(), true);

i=0;
}

i++;
}

 

选择较好的分词器

相同测试数据下由600M减少到380M,但是耗时长,时间换空间。

 

优化搜索性能

 

将索引放入内存
这是一个最直观的想法,因为内存比磁盘快很多。Lucene提供了RAMDirectory可以在内存中容纳索引:

Directory fsDir 
= FSDirectory.getDirectory(“/data/index/”, false);
Directory ramDir 
= new 
RAMDirectory(fsDir);
Searcher searcher 
= new IndexSearcher(ramDir);

 

优化时间范围限制

既然载入内存并不能提高效率,一定有其它瓶颈,经过测试发现最大的瓶颈居然是时间范围限制,那么我们可以怎样使时间范围限制的代价最小呢?
当需要搜索指定时间范围内的结果时,可以:
1
、用RangeQuery,设置范围,但是RangeQuery的实现实际上是将时间范围内的时间点展开,组成一个个BooleanClause加入到 BooleanQuery中查询,因此时间范围不可能设置太大,经测试,范围超过一个月就会抛BooleanQuery.TooManyClauses,可以通过设置 BooleanQuery.setMaxClauseCount(int maxClauseCount)扩大,但是扩大也是有限的,并且随着maxClauseCount扩大,占用内存也扩大
2
、用RangeFilter代替RangeQuery,经测试速度不会比RangeQuery慢,但是仍然有性能瓶颈,查询的90%以上时间耗费在 RangeFilter,研究其源码发现RangeFilter实际上是首先遍历所有索引,生成一个BitSet,标记每个document,在时间范围内的标记为true,不在的标记为false,然后将结果传递给Searcher查找,这是十分耗时的。
3
、进一步提高性能,这个又有两个思路:
a
、缓存Filter结果。既然RangeFilter的执行是在搜索之前,那么它的输入都是一定的,就是IndexReader,而 IndexReader是由Directory决定的,所以可以认为RangeFilter的结果是由范围的上下限决定的,也就是由具体的 RangeFilter对象决定,所以我们只要以RangeFilter对象为键,将filter结果BitSet缓存起来即可。lucene API已经提供了一个CachingWrapperFilter类封装了Filter及其结果,所以具体实施起来我们可以cache CachingWrapperFilter对象,需要注意的是,不要被CachingWrapperFilter的名字及其说明误导, CachingWrapperFilter看起来是有缓存功能,但的缓存是针对同一个filter的,也就是在你用同一个filter过滤不同 IndexReader时,它可以帮你缓存不同IndexReader的结果,而我们的需求恰恰相反,我们是用不同filter过滤同一个 IndexReader,所以只能把它作为一个封装类。
b
、降低时间精度。研究Filter的工作原理可以看出,它每次工作都是遍历整个索引的,所以时间粒度越大,对比越快,搜索时间越短,在不影响功能的情况下,时间精度越低越好,有时甚至牺牲一点精度也值得,当然最好的情况是根本不作时间限制。
下面针对上面的两个思路演示一下优化结果(都采用800线程随机关键词随即时间范围):
第一组,时间精度为秒:
方式 直接用RangeFilter 使用cache 不用filter
平均每个线程耗时
 10s 1s 300ms

第二组,时间精度为天

方式 直接用RangeFilter 使用cache 不用filter
平均每个线程耗时 900ms 360ms 300ms

 

由以上数据可以得出结论:
1
 尽量降低时间精度,将精度由秒换成天带来的性能提高甚至比使用cache还好,最好不使用filter
2
 在不能降低时间精度的情况下,使用cache能带了10倍左右的性能提高。

3、使用更好的分词器

  • 大小: 34.3 KB
分享到:
评论

相关推荐

    开放源代码的全文检索引擎Lucene

    开放源代码的全文检索引擎Lucene开放源代码的全文检索引擎Lucene开放源代码的全文检索引擎Lucene

    开放源代码的全文检索引擎Lucene.pdf

    ### 全文检索引擎Lucene知识点详解 #### 1. 全文检索系统与Lucene简介 ##### 1.1 全文检索与全文检索系统定义 全文检索是指计算机索引程序通过对文章中的每一个词建立索引,记录其在文章中的出现次数和位置,以...

    Lucene全文检索引擎

    **Lucene全文检索引擎** Lucene是Apache软件基金会的一个开源项目,它是一个高性能、全文本搜索引擎库,可以被集成到各种应用中实现全文检索功能。Lucene提供了完整的搜索功能实现,包括索引创建、文档存储、查询...

    Java全文检索引擎Lucene的应用.pdf

    ### Java全文检索引擎Lucene的应用 #### 一、引言 随着信息技术的飞速发展,尤其是数据库技术和数据库管理系统(DBMS)的广泛应用,全球范围内的数据量急剧增长。特别是在科学研究领域,面对海量的数据,传统的手工...

    开放源代码的全文检索引擎Lucene终稿.pdf

    《开放源代码的全文检索引擎Lucene终稿》是一份深度解析开源全文检索引擎Lucene的文档,旨在介绍Lucene的基本概念、系统架构以及源码实现。全文主要分为四个部分,详细阐述了Lucene的核心技术和应用。 在第一部分,...

    全文搜索引擎lucene入门

    全文搜索引擎Lucene是Apache软件基金会的一个开放源代码项目,它为Java开发者提供了一个高性能、可扩展的信息检索库。Lucene以其强大的文本搜索功能和高效的索引能力,在各种需要全文检索的应用场景中被广泛采用。...

    开放源代码的全文检索引擎Lucene收集.pdf

    《开放源代码的全文检索引擎Lucene收集》 全文检索系统是互联网信息处理的重要工具,它使得用户可以高效地在海量数据中查找相关信息。Lucene是Apache软件基金会下的一个开放源代码项目,它为开发者提供了强大的全文...

    全文检索引擎lucene的研究和使用(sping mvc + jpa 编写的案例)

    **全文检索引擎Lucene** Lucene是一个开源的全文检索库,由Apache软件基金会维护。它提供了文本分析、索引创建、搜索以及相关的工具,旨在帮助开发者构建强大的搜索功能。在这个项目中,Lucene被用于创建一个简易的...

    java全文搜索引擎 Lucene不是一个完整的全文索引应用,而是是一个用Java写的全文索引引擎工具包,它可以方便

    Java全文搜索引擎Lucene是Apache软件基金会的一个开源项目,它为开发者提供了一个强大的、高性能的、可扩展的全文检索工具包。Lucene的核心功能包括文本分析、索引创建、查询解析和搜索结果的排序。它不是预包装的...

    基于Java的全文检索引擎Lucene的分析与研究

    ### 基于Java的全文检索引擎Lucene的分析与研究 #### 一、Lucene简介 Lucene是一个用Java编写的全文检索引擎工具包,它由Doug Cutting创建,并作为Apache Jakarta项目的一部分开源。尽管Lucene本身不是一个完整的...

    开放源代码的全文检索引擎Lucene[归纳].pdf

    它的设计目标是为开发人员提供一个易于使用的工具,以便在自己的应用程序中集成全文检索功能,或者构建基于 Lucene 的完整搜索引擎。 【全文检索系统基础】 全文检索系统是基于全文检索理论建立的软件系统,其基本...

    lucene教程(全文搜索引擎)

    【Lucene教程(全文搜索引擎)】 Lucene是一个强大的开源全文搜索库,由Apache软件基金会维护。作为信息检索(IR)的框架,它提供了一个高效、可扩展的基础来构建搜索引擎和其他涉及文本检索的应用程序。不同于可以...

    开放源代码的全文检索引擎Lucene归类.pdf

    Lucene的创始人Doug Cutting是一位在全文索引和检索领域有着深厚经验的专家,他曾在V-Twin搜索引擎和Excite担任重要角色。Lucene起初是在作者个人网站发布,后来成为Apache开源项目的一部分。 【全文检索和Lucene的...

    基于java的全文搜索引擎Lucene

    Java全职搜索引擎Lucene是一个强大的开源工具,用于创建高效的全文索引和搜索功能。它由Apache软件基金会维护,被广泛应用于各种网站和应用程序中,以提供快速、精准的站内搜索体验。本教程将深入讲解如何使用Lucene...

Global site tag (gtag.js) - Google Analytics