二、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

相關文章
相關標籤/搜索