使用Solr 为大数据库搭建搜索引擎

使用Solr 为大数据库搭建搜索引擎

霍庆,刘培植

作者简介:霍庆,(1987-),女,硕士,通信与信息系统。

通信联系人:刘培植,(1957-),男,教授, 通信与信息系统. E-mail: liupz@https://www.360docs.net/doc/7110087872.html,

(北京邮电大学信息与通信工程学院,北京 100876) 摘要:如今信息快速发展,数据库信息不断增多,尤其是对于中文信息,传统的数据库搜索5 方式(like%%)不仅效率低下,而且搜索速度极慢,此时就需要为数据库搭建外部的中文搜索引擎。Apache Solr 是基于Lucene 的企业搜索引擎。本文介绍了Solr 的结构和特点,并使用它搭建大数据量的数据库搜索引擎,并在最后比较了数据库和搜索引擎的搜索时间,证明了使用Solr 能大大增加搜索效率。

关键词:搜索引擎;Solr;数据库

10

中图分类号:TP311

Use Solr to Build a Search Engine for Large Database

Huo Qing, Liu Peizhi

(School of Information and Communication Engineering,BeiJing University of Post and

15 Telecommunications, Beijing 100876)

Abstract: With the rapid development of information,the size of database is increasing, especially for Chinese information.The traditional database search mode (like%%)is not only inefficient,but also slow.At this point we need to build a full-text search engine for the database.Apache Solr is a Lucene-based enterprise search engine.This article describes Solr's structure and 20 characteristics.Then use it to build a search engine for a database with a large amout of data.Finally, a time comparison of using fuzzy query and search engine illustrates that the use of Solr can greatly increase the search efficiency.

Keywords: Search Engine; Solr; Database

25

0 引言

对于企业数据或者Wed 站点而言,中文内容的搜索是必不可少的功能之一。一般当数据量比较小的时候,各种信息内容都直接存储在数据库系统中,并且使用数据库提供的检索和查询功能进行中文内容搜索。但是随着数据量的增大,到百万千万乃至上亿条数据的时候,使用数据库中的like "%keyword%"查询,查询效率会急剧的下降。

30 由于数据库索引不是为全文索引设计的,因此,使用like "%keyword%"时,数据库索引是不起作用的,在使用like 查询时,搜索过程又变成类似于一页页翻书的遍历过程了,所以对于含有模糊查询的数据库服务来说,LIKE 对性能的危害是极大的[1]。 此外,使用like 查询的结果准确性也非常差,例如使用like "%北京%现代%":就不能匹配词序颠倒的“现代xxx 北京”。如果需要查询为“上市 公司2011”,要去查找2011年 上市的所有公司,数据

35 库查询用like 就做不到,而如果用搜索引擎建立了“上市 2011”,就可以查找到。

因此使用数据库直接查询来进行中文检索并不是个好的解决方案。而使用搜索引擎就可以避免数据库like 查询带来的低效性。而使用Solr 搭建自己的搜索引擎更可以避免使用其他大型搜索引擎的所遇到的更新慢,数据不准确等问题。

本文使用Solr 搭建数据库的搜索引擎,并对搜索结果进行对比,体现了使用搜索引擎

40 带来的查询高效率。

1Solr简介

1.1 Solr概念

Solr是一个基于Lucene的Java搜索引擎服务器。Solr 提供了层面搜索、命中醒目显示45

并且支持多种输出格式(包括 XML/XSLT 和 JSON 格式)。它易于安装和配置,而且附带了一个基于 HTTP 的管理界面。Solr已经在众多大型的网站中使用,较为成熟和稳定。

Solr 包装并扩展了 Lucene,所以Solr的基本上沿用了Lucene的相关术语。更重要的是,Solr 创建的索引与 Lucene 搜索引擎库完全兼容。通过对 Solr 进行适当的配置,某些情况下可能需要进行编码,Solr 可以阅读和使用构建到其他 Lucene 应用程序中的索引。此外,很多 Lucene 工具(如Nutch、 Luke)也可以使用 Solr 创建的索引[2]。

50

Solr 主要特性有:强大的全文检索功能,高亮显示检索结果,动态集群,数据库接口和电子文档(Word ,PDF 等)的处理。而且Solr 具有高度的可扩展,支持分布搜索和索引的复制。

1.2 Solr与Lucene

55

上文提到了Lucene,Lucene是目前最为流行的基于 Java 开源全文检索工具包。Solr 与Lucene 并不是竞争对立关系,恰恰相反Solr 依存于Lucene ,因为Solr 底层的核心技术是使用Apache Lucene 来实现的,简单的说Solr 是Lucene 的服务器化。需要注意的是Solr 并不是简单的对Lucene 进行封装,它所提供的大部分功能都区别于Lucene 。Solr和Lucene 的本质区别有以下三点:搜索服务器,企业级和管理。Lucene本质上是搜索库,不是独立60

的应用程序,而Solr是。Lucene专注于搜索底层的建设,而Solr专注于企业应用。Lucene 不负责支撑搜索服务所必须的管理,而Solr负责。所以说,一句话概括Solr: Solr是Lucene 面向企业搜索应用的扩展[3]。

2搜索引擎构建

2.1开发环境

操作系统:Windows 7

65

数据库:Oracle 10

Solr版本:apache-solr-1.4.0

分词器:mmseg4j-1.6.2

词库:sogou-dic

70

运行容器:Tomcat6

2.2系统结构

图1 系统架构

Fig. 1 System Architecture

75

图1显示的是搜索引擎的系统架构图。最底层为Oracle数据库,为测试大数据量的中文查询情况,数据库中存储1000万条记录。

中间为Solr搜索引擎核心,由于Solr是通过Servlet方式实现的,因此需要部署在容器上,本文选择最流行的搭建中小规模Web应用的Tomcat。由图中可知,Solr主要需要配置80

的为分词器、词库以及对应索引数据的配置文件,这些在下文会详细的进行说明。经过这些配置,使用DataImportHandler组件,可以通过HTTP控制生成需要的索引文件。

最上层为应用层,在这层中,可以灵活的使用搜索引擎的查询结果构建自己的搜索应用,本文不对查询结果进行处理,仅通过XML列出。此外Solr提供了SolrJ的API,用于索引进行管理,包括查询以及添加、删除索引,这部分在下文也会详细提到。

2.3数据模型

85

2.3.1数据库模型

本数据库为一个用户登记表,其中用户名为中文字段。表结构如下:

表1 数据库表结构

90

Tab. 1 Database Table Structure

列名数据类型长度

USERCODE VARCHAR2 10

USERNAME VARCHAR2 30

COMCODE VARCHAR2 8

VALIDSTATUS VARCHAR2 1

CHANGEDATE DATE 7 其中USERCODE为用户编号,USERNAME存放用户名,COMCODE存放公司代码,VALIDSTATUS存放目前状态,CHANGEDATE存放最后修改时间。数据表中共存放1000万条数据。

95

对于USERNAME,由于是本文主要查询对象,为了符合中文语义以及为了使查询更有

意义,创建时使用姓+名1+名2的方式。其中姓采用“中国姓氏大全”,名1和名2从GB2312 汉字库中随机抽取组合而成。

抽取名字部分关键代码如下,先初始化lastNameMap再随机抽取:

private static String randomLastName() {

100

int key = (int) (Math.random() lastNameMap.size());

String n1 = lastNameMap.get(key);

key = (int) (Math.random() lastNameMap.size());

String n2 = lastNameMap.get(key);

return n1 + n2;

}

105

public static void initLastNameMap() throws UnsupportedEncodingException {

int index = 0;

String str = "";

byte[] gbkBytes = null;

110

for (int segIndex = 0xb0; segIndex <= 0xf7; segIndex++) {

for (int charIndex = 0xa1; charIndex <= 0xfe; charIndex++) {

gbkBytes = new byte[] { (byte) (segIndex), (byte) charIndex };

str = new String(gbkBytes, "GBK");

lastNameMap.put(index++,

str);

115

System.out.println(str);

}

}

}

120

对于VALIDSTATUS,一般进行删除操作的时候为了数据安全,并不直接将数据从数据库中删除,而是使用VALIDSTATUS标识进行逻辑删除标识,为1时代表数据有效,为0是代表逻辑删除。

CHANGEDATE为了索引在增量添加的时候查找需要添加的增量部分而设定。

2.3.2索引模型

125

对于索引建立,对应数据库选定需要的内容,关键代码如下:

130

USERCODE

USERNAME

135

其中indexed="true"代表对这一栏建立索引,stored="true"代表存储这部分数据,待查询后可直接查看这部分数据。defaultSearchField为默认搜索的域。solrQueryParser defaultOperator代表当采用多个查询参数时使用OR来进行连接,例如查询“王一”系统中会按照“王OR一”来进行查找。

2.4分词和词库

140

分词器的选取不仅影响到整个引擎的效率还对检索结果的准确度有决定性的作用。目前比较流行的分词器主要有paoding ,imdict ,mmseg4j ,ik。paoding :Lucene中文分词“庖

丁解牛” Paoding Analysis;imdict :imdict智能词典所采用的智能中文分词程序;mmseg4j :

用 Chih-Hao Tsai 的 MMSeg 算法实现的中文分词器;ik :采用了特有的“正向迭代最细

145

粒度切分算法“,多子处理器分析模式。经过从开发者及开发活跃度,用户自定义词库,

速度,算法和代码复杂度,帮助文档等方面[4]综合考虑,决定使用Mmseg4j分词器。MMSeg

算法有两种分词方法:Simple和Complex,都是基于正向最大匹配。Complex 加了四个规

则过虑。官方说:词语的正确识别率达到了 98.41%。mmseg4j 已经实现了这两种分词算法,

1.6版在complex基础上实现了最多分词(max-word)。

2.5索引管理

150

2.5.1数据库导入配置

执行数据库导入DataImportHandler需要对Solr进行一些数据库相关配置。关键配置如下:

155

url="jdbc:oracle:thin:@192.168.2.190:1521:orcl" user="arch4platform"

password="arch4platform"/>

这部分是配置数据库关联数据,配置了数据库名,访问用户名密码等关键信息。

160

deltaQuery="select USERCODE from PRPDUSER where to_char (CHANGEDATE , 'yyyy-mm-dd hh:mi:ss' ) > '${https://www.360docs.net/doc/7110087872.html,st_index_time}'"

query="select from PRPDUSER"

deltaImportQuery="select from PRPDUSER where USERCODE ='$ {https://www.360docs.net/doc/7110087872.html,ERCODE}'"

165

deletedPkQuery="SELECT from PRPDUSER where VALIDSTATUS ='0'">

这部分为执行导入时非常重要的部分。deltaQuery和deltaImportQuery为执行增量导入时的数据库查询语句,选择CHANGEDATE的时间大于上次执行导入的时间的条目,实现

部分增量导入,节省了全部导入重复内容浪费的时间。Query未执行完全导入时执行的数据

库查询语句。

170

2.5.2查询添加删除索引

Solr 提供了一个易于使用的、基于 Java 的 API,它避免了 HTTP 链接和 XML 命令的所有弊端。这个称为 SolrJ 的新客户机使得通过 Java 代码处理 Solr 更加轻松。SolrJ API

通过良好定义的方法调用简化了索引创建、搜索、排序和分类。

本文中使用SolrJ来进行索引的添加删除,以及执行中文搜索。

175

查询关键代码如下:

CommonsHttpSolrServer solrServer = new CommonsHttpSolrServer(SOLR_URL);

SolrQuery query = new SolrQuery();

query.setQuery(":");

QueryResponse rsp = solrServer.query( query );

180

SolrDocumentList docs = rsp.getResults();

for ( Object obj:docs) {

SolrDocument doc=(SolrDocument)obj;

String USERNAME = (String) doc.getFieldValue("USERNAME");

String USERCODE = (String) doc.getFieldValue("USERCODE");

185

}

通过SolrJ查询只需先建立连接CommonsHttpSolrServer,然后定义SolrQuery,添加查询语句setQuery(),然后就可以通过QueryResponse类型的对象读出查询结果。

添加单独索引时,在建立连接的基础上创建SolrInputDocument类型,通过addField()方法添加相应的索引域和内容,最后执行add()方法以及commit()方法即可。

190

删除单独索引时,在建立连接的基础上执行deleteByQuery()方法,再commit()就可以完成根据查询结果删除索引。

3结果分析

3.1 Solr开销

Solr导入千万级数据花费20分52秒。

195

索引文件占用空间643M。

图2导入结果

Fig. 2 Import Results

3.2搜索时间对比

200

查询抽取JAVA中文字库GB2312中的字,使用单字查询。Solr采用SolrJ接口,读取查询时间rsp.getQTime(),数据库采用模糊查询like%%。

经1000次统计测试,Solr平均查询时间:3.07MS,数据库平均查询时间:7631.1MS。可以看出,使用搜索引擎查询的时间是数据库查询的千分之一量级。

4结论

205

在进行海量数据搜索的时候,如果仅仅使用数据库的技术,那将带来非常大的痛苦,速度会是最大的瓶颈,此外还会带来搜索结果不匹配等令人沮丧的问题。本文提出了使用Solr 建立数据库搜索引擎,并结合具体代码简单说明如何构建Solr搜索引擎,并在最后进行了比较,Solr的搜索引擎优势是显而易见的。

210

[参考文献] (References)

[1] 车东. Lucene:基于Java的全文检索引擎简介[OL]. [2009-03-20]. https://www.360docs.net/doc/7110087872.html,/tech/lucene.html

[2] p_x1984. 企业级搜索引擎Solr使用指南[OL].[2009-07-31]. https://www.360docs.net/doc/7110087872.html,/blog/437088

[3] netoearth. Apache Solr 介绍[OL].[2011-4-4]. https://www.360docs.net/doc/7110087872.html,/html/201104/apache-solr-介绍.htm 215

[4] 石青SEO. 基于Lucene的最流行的分词法[OL]. [2009-8-30]. https://www.360docs.net/doc/7110087872.html,/Html/?2428.html

相关文档
最新文档