二、oracle全文检索

公司项目须要实现馆藏库的全文检索,可是只有一个查询,若是使用lucene的话不太方便,经过查找资料,发现oracle自带全文检索功能。通过测试,oracle实现全文检索很方便,很实用。oracle

注意:本例子针对于表中某一字段的全文检索。如ceshi表中name字段下全部数据的检索。oop

环境:oracle11g,oracle链接为search,表为ceshi,字段有id,name测试

1:进行准备工做,oracle全文检索须要ctxsys用户的支持,其实主要须要使用ctxsys用户下的ctx_ddl这个包,因此咱们使用system帐户解锁stxsys用户。优化

1.1:使用system帐户创建链接spa

1.2:解锁stxsys用户,分别执行如下两个命令。并将权限赋予arc_master用户(注意:arc_master用户是我本身新建的用户,可使用不一样的用户名).net

对ctxsys用户解锁,以得到ctx_ddl包的操做权。进入system用户,输入以下命令,解锁ctxsys用户blog

alter user ctxsys account unlock;排序

将ctx_ddl包的操做权限赋给arc_master用户。索引

grant execute on ctx_ddl to arc_master; token

2:准备工做完成以后,使用arc_master用户链接(链接如图1),开始测试。

2.1:创建测试表

create table ceshi( 

id number, 

name varchar2(50) 

); 

2.2:插入测试数据

insert into ceshi values(111,'重庆市沙坪坝区'); 

insert into ceshi values(211,'成都市青羊区'); 

insert into ceshi values(311,'北京市西城区'); 

insert into ceshi values(411,'重庆市两江新区'); 

insert into ceshi values(511,'上海市浦东新区金桥镇'); 

insert into ceshi values(611,'上海东方明珠'); 

insert into ceshi values(711,'江苏省无锡市国家软件园'); 

insert into ceshi values(811,'成都市天府软件园');

2.3:建立分析器,建立一个“chinese_lexer”分析器,名称为my_lexer。

exec ctx_ddl.create_preference ('my_lexer', 'chinese_vgram_lexer'); 

这个分析器的做用就是name字段的全部数据分词,以便于后面建立索引。如图所示:

词法分析器有3种类型:

* 'CHINESE_VGRAM_LEXER'仅用于中文,提取标示符更大,无效标示符较多;

* 'CHINESE_LEXER' 仅用于中文,效率高一些更准确可靠一些;建议使用

* 'BASIC_LEXER'仅用于英文;

2.4:建立过滤词组,,好比对公司名称进行检索时,确定不但愿输入“有限公司”、“公司”等关键词时,也会有搜索结果。

exec ctx_ddl.create_stoplist('my_stoplist'); 

自定义须要过滤的词组,建立了一个名为“my_stoplist”的过滤词组,“有限公司”、“股份有限公司”这两个词组不会被建立为索引。

exec ctx_ddl.add_stopword('my_stoplist','有限公司');  

exec ctx_ddl.add_stopword('my_stoplist','股份有限公司'); 

2.5:建立索引,在ceshi_INDEX表中的name字段上建立索引,索引类系那个为context类型,该索引用到的分析器为前面定义的my_lexer,该索引用到的过滤词组为前面定义得my_stoplist。

create index ceshi_INDEX on ceshi(name) indextype is CTXSYS.CONTEXT parameters('lexer my_lexer stoplist my_stoplist'); 

2.6:使用索引,此时的数据是没有通过排序。经过如下的查询语句就能够很快的查处所需的内容。

select * from ceshi where contains(name,'北京市')>0; 

2.7:虽然内容查出来了,不过数据是无序的。有的时候须要根据状况决定查询结果出现的前后顺序。能够按照关键字的匹配程度排序,这里的score是oracle全文检索对关键字的匹配程度所计算的分数,contains里的最后一个参数“1”就是对这个分数的一个标识。

select score(1),y.* from ceshi y where contains(name,'软件',1)>0 order by score(1) desc; 

2.8:经过以上步骤基本就完成了oracle检索。不过当咱们添加新数据的时候,新数据并无建立新的索引,此时须要索引同步和索引优化。

索引同步

exec ctx_ddl.sync_index('ceshi_index');

索引优化

exec ctx_ddl.optimize_index('ceshi_index','full');

3:最后一个问题,就是用户输入的关键字也须要进行分词,由于前面分词图能够看到,词被分红一块一块,若是用户输入的词不拆分,有可能查不出来数据。(最后这一步骤的实现不理解)

首先须要先建立一个POLICY过程,这里建立了一个名称为my_policy的policy过程,分析器用到了前面建立的my_lexer分析器

exec CTX_DDL.CREATE_POLICY('MY_POLICY', LEXER => 'my_lexer');  

create or replace function p_split_chinese(p_input in varchar2)  

    return varchar2 as   

       v_tab CTX_DOC.TOKEN_TAB;  

       v_return VARCHAR2(323767);  

    begin  

       CTX_DOC.POLICY_TOKENS('my_policy',p_input,v_tab);  

       for i in 1..v_tab.count loop  

          v_return := v_return || ',' || v_tab[i].token;  

       end loop;  

       return LTRIM(v_return,',');  

     end; 

select F_SPLIT_CHINESE('重庆天府') from dual;

F_SPLIT_CHINESE('重庆天府')


最后,经过这些步骤,咱们就能够根据jdbc来实现功能了。

 参考博文:http://blog.csdn.net/linfssay/article/details/7679353

相关文章
相关标签/搜索