日期:2014-05-16  浏览次数:20972 次

APACHE Lucene 的使用

用了下Lucene的全文搜索,这次的使用没多大复杂度,只是针对数据库的检索,先看下理论的东西,加固下自己的理论思想(这写理论也是看别人文档来的,自己领悟不了这么专业的词汇.....)。

1 什么是全文搜索。

全文搜索(full-text-Retrieval)是以文本为检索对象,找出含有指定词汇的文本。全面、准确、和快速是衡量全文搜索系统的关键指标。在信息检索工具中,全文搜索最通用性和实用性的。

2 全文搜索不同以数据库搜索

全文搜索不同与数据库查询。数据库的查询like 模糊查询是不一样的,如果使用like查询会先如下问题:

1.0 匹配效果:如搜索ant会搜索出planting。这样会搜索出很多无关的信息。

2.0相关度排序:查出的结果没有相关度排序,不知道我想要的结果在哪一页。我们在使用百度搜索时,一般不需要翻页,为什么?因为百度做了相关度排序:为每一条结果打一个分数,这条结果越符合搜索条件,得分就越高,叫做相关度得分,结果列表会按照这个分数由高到低排列,所以第1页的结果就是我们最想要的结果。

3.0 查询速度:全文检索的速度比sql like查询快。这是因为查询方式不同造成的,以查字典举例:数据库的like就是一页一页的翻,一行一行的找,而全文检索是先查目录,得到结果所在的页码,再直接翻到这一页。

3.Lucene 的工作原理:

?

看着Lucene的API,看得出来索引库是个核心区域。

?

索引库:

索引库是一个目录,里面是一些二进制文件,就如同数据库,所有的数据也是以文件的形式存在文件系统中的。我们不能直接操作这些二进制文件,而是使用Lucene提供的API完成相应的操作,就像操作数据库应使用SQL语句一样。

对索引库的操作可以分为两种:管理与查询。管理索引库使用IndexWriter,从索引库中查询使用IndexSearcherLucene的数据结构为DocumentFieldDocument代表一条数据,Field代表数据中的一个属性。一个Document中有多个FieldField的值为String型,因为Lucene只处理文本。

我们只需要把在我们的程序中的对象转成Document,就可以交给Lucene管理了,搜索的结果中的数据列表也是Document

?

配置Lucene的工作环境:我用的3.0.x版本

?

要加入的jar包有:

llucene-core-3.0.1.jar(核心包)

lcontrib\analyzers\common\lucene-analyzers-3.0.1.jar(分词器)

lcontrib\highlighter\lucene-highlighter-3.0.1.jar(高亮)

lcontrib\memory\lucene-memory-3.0.1.jar(高亮)

lIKAnalyzer3.2.3.jar(中文分解词,这jar不在Lucene里面,需要去额外下载)

4.开始Hello world.

首先,我需要把Lucene所需要的基本功能给抽象出来,我们看Lucene的API,流程图可以看出我们都是针对索引库进行操作,需要用到IndexWrite的CRUD 写入、更新、删除索引库和IndexSearcher来搜索索引库的内容。

我们需要一个接口来描述这些基本方法:

/***
 * Lucene 索引基本操作接口
 * @author share
 *
 * @param <E>
 */
public interface IndexService<E> {
 void save(E entity);//添加
 void delete(Long id);//删除
 void update(E entity);//更新,针对打数据的操作,可以能不进行更新操作,直接delete在save记录。
 Page<E> search(Page<E> page,String queryString);//按条件分页查询搜索
 
}

?

贴Page对象的基本方法:

public class Page<T> {
 //-- 公共变量 --//
 public static final String ASC = "asc";
 public static final String DESC = "desc";
 
//-- 分页参数 --//
 protected int pageNo = 1;
 protected int pageSize = 20;
 protected boolean autoCount = true;
 
//-- 返回结果 --//
 protected List<T> result = new ArrayList<T>();
 protected long totalCount = 0;
 protected int totalPages = 0;
 protected int searchFlag=0;

 
//省略getter 和setter方法
 
}

?

设计一个LuceneUtils类

?

/** 
* 使用 IndexWriter 进行保存或更新操作时, 
* 若不手动调用