您的位置:首页 > 其它

Lucene入门

2018-01-21 19:28 246 查看

Lucene入门

1.Lucene介绍

什么是Lucene?

Lucene是apache下的一个开放源代码的全文检索引擎工具包。Lucene可以实现全文检索功能,Lucene就是一个工具包(提供了Jar包,实现全文检索的类库)。Lucene只是一个引擎,只是一个工具包,如果使用Lucene开发全文检索功能,Lucene是不能单独运行的。


程序员或开发工程师使用lucene提供的类库可以开发全文检索功能。

2.全文检索技术的应用场景

使用全文检索技术可以实现搜索引擎(百度、google。。),搜索引擎可以搜索互联网上所有的内容(网页、pdf电子书、视频、音乐)。

Lucene和搜索引擎的区别:搜索引擎是对外提供全文检索服务,是可以单独运行。Lucene只是一个工具包不能单独运行的,需要在project中加入lucene的jar包,最终project在JVM运行。

使用全文检索技术可以实现站内搜索,站内搜索只能搜索本网站的信息(网页、pdf电子书、视频、音乐、关系数据库中的信息等等),比如:电商网站搜索商品信息,论坛网站搜索网内帖子…

3.Lucene实现全文检索过程–概括

全文检索的定义:

全文检索首先将要搜索的目标文档中的词提取出来,组成索引,通过查询索引达到搜索目标文档的目的。

这种先建立索引,再对索引进行搜索的过程就叫全文检索(Full-text Search)

如下图Lucene实现全文检索过程(全文检索实现过程):



全文检索过程分为 索引、搜索两个过程。

索引:

1、从关系数据库中、互联网上、文件系统采集源数据(要搜索的目标信息)

源数据的来源是很广泛的。

2、将源数据采集到一个统一的地方,要创建索引,将索引创建到一个索引库(文件系统)中

从源数据库中提取关键信息,从关键信息中抽取一个一个,词和源数据是有关联。

索引库中就是一个一个的库。

搜索:

3、用户执行搜索(全文检索)编写查询关键(全文检索查询语法,类似关系数据库中的sql)

4、从索引库中搜索索引,根据查询关键字搜索索引库中的一个一个词

5、展示搜索的结果。

创建索引时词和源数据有关联,索引库中记录了这个关联,如果找到了词就说明找到了源数据(http的网页、pdf电子书)。

4.需求

要用Lucene实现站内搜索,要搜索图书信息。

图书信息在关系数据库中:



5.环境准备

mysql:5.1

java:1.7

Lucene:

Lucene是开发全文检索功能的工具包,从官方网站下载Lucene4.10.3,并解压,lucene的jar加入工程中使用即可。

官方网站:http://lucene.apache.org/

版本:lucene4.10.3

使用的jar:

mysql5.1驱动包:mysql-connector-java-5.1.7-bin.jar

lucene核心包:lucene-core-4.10.3.jar

lucene分析器通用包:lucene-analyzers-common-4.10.3.jar

lucene查询解析器包:lucene-queryparser-4.10.3.jar

junit包:junit-4.9.jar

开发工具:IDEA maven

pom.xml配置如下,其中的版本可根据自己的本地仓库进行修改

<properties>
<luncene-version>4.10.3</luncene-version>
</properties>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.27</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-core</artifactId>
<version>${luncene-version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.9</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-queryparser</artifactId>
<version>${luncene-version}</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-analyzers-common</artifactId>
<version>${luncene-version}</version>
</dependency>
</dependencies>


6.索引部分

6.1.为什么要采集数据?

全文检索要搜索的源数据的格式是多种多样的,比如:互联网站上的网页(html)、互联网上的音乐(mp3..)、视频(avi..)、pdf电子书等。

全文检索搜索的这些数据称为非结构化数据

什么是非结构化数据?

结构化数据:指具有固定格式或有限长度的数据,如数据库,元数据等。

非结构化数据:指不定长或无固定格式的数据,如邮件,word文档等

如何搜索结构的数据?

由于结构化数据是固定格式,所以就可以针对固定格式的数据设计算法来搜索,比如数据库like查询,like是根据关键字去搜索的内容中顺序扫描关键字。

select * from book where description like ‘%java%’

description 的内容很多,如果要顺序扫描的算法,速度很慢的。

如何搜索非结构的数据?

需要将所有要搜索的非结构化数据通过技术手段采集到一个固定的地方,将这些非结构化的数据想办法组成结构化的数据,再以一定的算法去搜索。

6.2.如何采集数据

针对不同的源数据,使用不同的技术进行采集:

1、针对互联网上的数据,使用
ebbb
http协议抓取html网页到本地,生成一个html文件。

2、针对关系数据库中的数据,连接数据库读取表中的数据。

3、针对文件系统中的数据,通过流读取文件系统的文件。

以上技术中使用第一种较多,因为目前全文检索主要搜索数据的来源是互联网,搜索引擎使用一种爬虫程序抓取网页( 通过http抓取html网页信息),以下是一些爬虫项目(了解):

Solr(http://lucene.apache.org/solr) ,solr是apache的一个子项目,支持从关系数据库、xml文档中提取原始数据。

jsoup(http://jsoup.org/ ),jsoup 是一款Java 的HTML解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API,可通过DOM,CSS以及类似于jQuery的操作方法来取出和操作数据。


6.3.采集数据Dao

针对本例子的需求,从关系数据库中采集 book表的数据。

创建dao接口读取book表中的数据。

6.3.1.po实体类



6.3.2.Dao接口





6.4.索引文件逻辑结构

索引文件: 将源数据创建索引,最终以索引文件方式存储到文件系统中。

索引文件逻辑结构图:



文档域:

对非结构化的数据统一格式为document文档格式,

一个文档有多个field域,不同的文档其field的个数可以不同,建议相同类型的文档包括相同的field。

本例子一个document对应一 条 book表的记录

索引域:

索引域的用于搜索的,搜索程序将从索引域中搜索一个一个词,根据词找到对应的文档。

之所以根据词可以找到文档,是因为词是从document中的Field内容抽取出来的。

将Document中的Field的内容进行分词,将分好的词创建索引,索引=Field域名:词(表示从document中的哪个Field抽取的词)

6.5.创建Docuemnt

使用lucnene的api创建Document。

一个document对应一条book表的记录。

代码如下:



6.6.分词

在对Docuemnt中的内容索引之前需要经过分词、过虑两步。

分词就是将原始文档内容切分成一个一个的词也就是将Document中Field的value值切分成一个一个的词。

过虑包括去除标点符号、去除停用词(的、是、a、an、the等)、大写转小写、词的形态还原(复数形式转成单数形参、过去式转成现在式。。。)等。

Lucene作为了一个工具包提供不同国家的分词器,如下图:



本例子使用StandardAnaylzer标准分词器,支持英语内容分词。

6.7.创建索引

索引过程:



代码:



创建索引成功:



6.8.使用Luke查询索引文件内容

Luke作为Lucene工具包中的一个工具(http://www.getopt.org/luke/),用于查询、修改lucene的索引文件。

打开Luke方法:

cd luke所在目录







7.搜索部分

7.1.搜索过程



1、用户定义查询语句,用户确定查询什么内容(输入什么关键字)

指定查询语法,相当于sql语句。

2、IndexSearcher索引搜索对象,定义了很多搜索方法,程序员调用此方法搜索。

3、通过IndexReader索引读取对象,对应的索引维护对象IndexWriter

IndexReader读取索引目录 的索引文件

4、IndexReader需要索引流对象读取索引目录内容,使用FSDirectory文件系统流对象

5、IndexSearcher搜索完成,返回一个TopDocs(匹配度高的前边的一些记录)

7.2.输入查询语句

通过Query查询对象输入查询语句。

同数据库的sql一样,lucene全文检索也有固定的语法:

最基本的有比如:AND, OR, NOT 等

举个例子,用户输入语句:description:java AND lucene

意义:查询description域内容有java并且有lucene的文档。

7.3.搜索语法分析

由于查询语句为特殊的语法所以lucene会首先对语法进行分析,判断语法关键字的正确性,比如NOT、AND、OR,分别抽取出语法关键字和搜索关键字。

7.4.分词

和索引过程的分词一样,这里要对用户输入的关键字进行分词,一般情况索引和搜索使用的分词器一致。

比如:输入搜索关键字“java编程”,分词后为java和编程两个词,与java和编程有关的内容都搜索出来了,如下:



7.5.搜索代码

//搜索索引
@Test
public void searchIndex() throws Exception{

//分词,所有过程使用的分析器要和索引时使用的分词器一致
Analyzer analyzer = new StandardAnalyzer();

//查询分析器
//第一个参数:指定默认搜索的域,第二个:分词器
QueryParser queryParser = new QueryParser("description",analyzer);

//创建查询对象
Query query = queryParser.parse("description:java");

//创建索引目录的流对象,指定索引目录的位置
Directory directory = FSDirectory.open(new File("D:\\temp\\lucene-indexdata"));

//索引读取对象
//指定读取索引的目录
IndexReader indexReader = IndexReader.open(directory);

//索引搜索对象
IndexSearcher indexSearcher = new IndexSearcher(indexReader);

//执行搜索
//第一个参数:query查询对象,第二个:取出匹配度高的前50条
TopDocs topDocs = indexSearcher.search(query,50);

//取出匹配上的文档
ScoreDoc[] scoreDocs = topDocs.scoreDocs;
for (ScoreDoc scoreDoc:scoreDocs){
//document的id
int docID = scoreDoc.doc;

//从indexReader根据docID获取document
Document doc = indexReader.document(docID);

//取出doc中的field域的内容
//参数指定field域名
String id = doc.get("id");
String name = doc.get("name");
float price = Float.parseFloat(doc.get("price"));
String pic = doc.get("pic");

System.out.println("--------------------");
System.out.println("图书的id:"+id);
System.out.println("图书的名称:"+name);
System.out.println("图书的价格:"+price);
System.out.println("图书的图片:"+pic);
}
indexReader.close();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  lucene 全文检索