【摘要】本文介绍了传统的基于关系数据库like检索的网站站内检索方案的不足,对开源的Lucene进行了介绍,对比了Lucene与关系数据库的区别。提出了网站站内检索开发的“关系数据库+全文数据库”的方案,分析了关系数据库与全文数据库间数据同步常见几种方案的不足,提出基于JMS构建的事件触发异步消息同步方案。
【关键词】Lucene、全文检索、自动切分词、Spider、java、J2EE、JMS、Event、Listener、JDBC、DAO、事务、表现层、业务层、数据持久层、
Oracle、索引、Like、全表扫描
目 录
摘要 3
关键词 3
一、前言 3
二、基于Java的全文索引/检索引擎——Lucene介绍 7
(一)全文检索的实现机制 8
(二)全文检索 ≠ like "%keyword%" 9
(三)Lucene的创新之处 11
(四)关于亚洲语言的的切分词问题 13
三、在开发项目中使用Lucene 14
(一)Lucene的安装 14
(二)创建Lucene全文库 14
(三)全文检索 15
四、利用Lucene实现站内检索 16
(一)J2EE开发三层架构 16
(二)“关系数据库+全文数据库”的双数据库方案 17
(三)数据同步——常见方案 17
(四)基于事件触发的异步消息通知机制实现数据同步 19
五、结论 20
六、参考资料 20
一、前言
自从有了计算机以后,人类开始用计算机保存信息,有保存,就有查找,于是检索技术诞生了。文本检索技术的发展从最初的SMART文档检索系统(使用grep命令检索)到Altavista搜索引擎(人工收录),到现在的搜索巨头Google(依靠spider抓取网页),其发展可谓日新月异、与时俱进,人们开始习惯互联网的搜索时代,站内检索的需求也逐渐显露出来。下面列举需要站内检索的五大理由:
1、所寻即所得。
信息量总在不断增长,而访问者的耐心却逐渐下降。据统计,每需要多点击一次鼠标,就有三分之一的用户选择放弃。这意味着100个访问者进入我们的网站,如果需要点击三次鼠标才能找到所需要的东西,那么就只剩下不到4个人了。根据第十一次中国互联网信息调查表明,53.1%的人上网是为了获取信息[3],大部分网站的目的是让外界了解自己,了解的人越多,效果就越好。把访问者最想要的返回给用户,就可让更多的用户了解自己,这样站内检索成为必然选择。
2、了解访问者的意图。
管理大师彼得.德 鲁克说:“一定要知道你的客户想要什么?”客户的需求永远都是最重要的,因此我们总在分析我们的客户在哪里及他们需要什么。所有访问我们网站的人都可能是 我们的潜在客户,了解他们的意图对于我们做决策很重要。站内检索技术可以实现这个功能,站内检索的日志功能可以记录每个访问者的检索词和检索结果,这是访 问者意图的最直接的表现。通过分析这些信息,我们还可以调整网站结构,把访问者最想要的放在明显的位置(了解我们的人就多啦)。这个理由经常被人忽视,我在这里放在第二位也是希望引起大家重视,特别是那些已经使用站内检索的网站所有者。
3、 符合网民习惯。
根据调查表明,68.3% 的上网者经常使用搜索引擎。大部分人已经习惯通过检索来找到他们想要的东西,而不是按照某个栏目一级一级往下找。在网站内访问者要是没看见那熟悉的按钮会多少有些不习惯。在心理学角度讲,人们如果对某个事物不习惯很容易产生厌 烦情绪,这也就是为什么你第一次去某个地方会觉得特别远,要是路熟了这种感觉就消失了。用户就是上帝,为了上帝我们也需要使用站内检索。
4、 提升网站信息价值。
我们经常会发生这样的事情:明明记得有一篇写关于吃香辣虾的文件,就是想不起存放在什么地方了。访问者也有类似困扰,只记得某个网站上说了关于张国荣跳楼的消息,但不知道具体的链接在哪里。另外,要是隐藏在目录很深的html文档可能自从网站建立到整个网站关闭也没有一个人看过,这些都不是我们所想要的。站内检索毫无疑问可以解决上述问题。同时,按照一个主题把所有相关文档提供 给访问者,可以让访问者更全面的了解他所想要的东西,这增加了网站信息间的组织性和逻辑性,方便了访问者的使用,提升用户体验度。
5、身份的象征。
有没有站内检索其实已经不只是用户体验度的问题了,还是一个网站专业身份的象征。浏览国外公司的网站,会发现几乎所有网站都在首页最明显的区域放置了一个搜 索框,这传达的信息是:专业的网站都有站内检索。网民的心态是:我用不用,你管不着,你要是没有就说明你不够专业。 为了树立形象,也需要使用站内检索。
还有一个问题:为什么有了搜索引擎还需要站内检索?用搜索引擎不是直接可以查到吗?这其中有两个原因:
(1)从经验看,搜索结果的前几页信息对于用户是真正有意义的。搜索“羽毛球”这个关键词,你会搜索到235,000个网页,也不知道我公司的排在第10,000页还是10,001页,搜索者可能永远也不会去看。
(2)搜索引擎通过网络Spider收集网页,对于网站内隐藏很深的网页很难索引到的。特别是对于需要完成用户身份验证(即需要用户到指定的入口登录系统)后才能访问的网页,虽然大多数搜索引擎的Spider都可以设定策略,在抓取网页前先访问这些入口,但是,随着技术的发展,越来越多的网站在用户登录时,都采用了图形验证码的安全措施,用户必须手工输入加入干扰背景后的验证码图片内容后才能登录,出于OCR识别技术的困难,spider对付这类图形验证码往往是力不从心的。
从应用系统设计的情况来看,传统的网站站内搜索,通常采用数据库字段like查询来实现的,这类检索通常有这些问题:
(1)响应速度
关系数据库的检索效率与是否有效利用索引有关。一个“fieldname like ‘%keyword%’”的检索语句,通常都是对数据表进行全表扫描,没有利用数据库索引的。
以Oracle数据库为例,我们使用以下的DDL语句创建一张表:
create table MUD_ACCOUNT
(
ID NUMBER(10) not null,
MOBILE VARCHAR2(255),
NICK VARCHAR2(255),
CREATETIME DATE
);
create index IDX_MUD_ACCOUNT on MUD_ACCOUNT (mobile);
在这里,我们创建了一个MOBILE字段的普通索引。
我们使用“select * from mud_account t where t.mobile='08713819455'”这条语句进行检索,查看这条语句的查询计划可以看到,这次查询,有效的利用了IDX_MUD_ACCOUNT这条索引,检索的成本和响应速度较快。
SELECT STATEMENT, GOAL = RULE
TABLE ACCESS BY INDEX ROWID Object owner=WUYU Object name=MUD_ACCOUNT
INDEX RANGE SCAN Object owner=WUYU Object name=IDX_MUD_ACCOUNT
但是,当我们使用“select * from mud_account t where t.mobile like '%08713819455%'“这样的语句进行检索时,oracle实际上进行的是全表扫描,没有利用到任何一条索引。如果数据量特别大,那么这条检索的效率是可想而知的了。
SELECT STATEMENT, GOAL = RULE
TABLE ACCESS FULL Object owner=WUYU Object name=MUD_ACCOUNT
(2)对于复杂检索条件的支持较困难
在实际情况下,往往需要支持一些复杂的检索条件,比如OR、AND、NOT这类逻辑关系。传统的站内检索方式往往对这些复杂检索采用拼接SQL的方法来实现。
以上面创建的MUD_ACCOUNT表为例,用户的检索关键词是“0871 OR 455 NOT 08713819455”,我们不得不在查询请求时动态构造这样的查询语句
select * from mud_account t
where t.mobile like '%0871%'
and t.mobile like '%455%'
and t.mobile!='08713819455'
当用户再输入新的检索条件时,我们就再次动态构造一个查询语句。
首先是对oracle的性能影响。从oracle来看,由于每次都要动态构建查询语句,查询语句的再次利用率相当低,大量的预处理后的sql语句规程在Shared Pool里,shared pool很快就会被耗干,于是“ORA-04031”的错误就出现了。
其次是安全的问题,由于互联网上有大量的恶意攻击行为,对于基于数据库的应用系统,最常见的攻击就是“SQL注入”攻击。为了处理复杂的检索请求而采用的这种动态构建查询语句的办法,对于比较巧妙的SQL注入往往显得很无力。
从软件质量来看,这种动态构建查询语句的处理办法,尤其是查询非常复杂的时候,我们会在程序代码里面看到大段大段if else之类的语句出现,程序显得非常复杂,也非常脆弱。这样的代码,开发、测试、维护都非常麻烦。... ... ... ...
... ... ... ...
TAG: 全文检索 事件 触发机制




