select * from t_zhzx_xjjq_new t where contains(t.bjnr,'有人車') > 0
create index qw_index_bjnr on t_zhzx_xjjq_new(bjnr) indextype is ctxsys.context
drop index ceshi_INDEX force
Begin
ctx_ddl.create_preference('my_lexer', 'chinese_lexer');
End
Begin
ctx_ddl.drop_preference('my_chinese_lexer');
End;
Create index IDX_TBL_COL on t_zhzx_xjjq_new (bjnr) indextype is ctxsys.context parameters ('lexer my_chinese_lexer');
-----------------
--對ctxsys用戶解鎖,以獲得ctx_ddl包的操作權。進入system用戶,輸入如下命令,解鎖ctxsys用戶
alter user ctxsys account unlock;
--將ctx_ddl包的操作權限賦給arc_master用戶。
--建立測試表
create table ceshi(
id number,
name varchar2(50)
);
--插入測試數據
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,'成都市天府軟件園');
commit;
--創建分析器,創建一個“chinese_lexer”分析器,名稱爲my_lexer。
exec ctx_ddl.create_preference ('my_lexer', 'chinese_lexer');
--這個分析器的作用就是name字段的所有數據分詞,以便於後面創建索引。如圖所示:
--創建過濾詞組,,比如對公司名稱進行檢索時,肯定不希望輸入“有限公司”、“公司”等關鍵詞時,也會有搜索結果。
exec ctx_ddl.create_stoplist('my_stoplist');
--自定義需要過濾的詞組,創建了一個名爲“my_stoplist”的過濾詞組,“有限公司”、“股份有限公司”這兩個詞組不會被創建爲索引。
exec ctx_ddl.add_stopword('my_stoplist','有限公司');
exec ctx_ddl.add_stopword('my_stoplist','股份有限公司');
exec ctx_ddl.drop_stoplist('my_stoplist');
--創建索引,在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');
--使用索引,此時的數據是沒有經過排序。通過以下的查詢語句就可以很快的查處所需的內容。
select * from ceshi where contains(name,'北京市')>0;
--雖然內容查出來了,不過數據是無序的。有的時候需要根據情況決定查詢結果出現的先後順序。可以按照關鍵字的匹配程度排序,這裏的score是oracle全文檢索對關鍵字的匹配程度所計算的分數,contains裏的最後一個參數“1”就是對這個分數的一個標識。
select score(1),y.* from ceshi y where contains(name,'軟件',1)>0 order by score(1) desc;
--通過以上步驟基本就完成了oracle檢索。不過當我們添加新數據的時候,新數據並沒有創建新的索引,此時需要索引同步和索引優化。
--索引同步
exec ctx_ddl.sync_index('ceshi_index'); --新增的數據之後必須執行該命令
--索引優化
exec ctx_ddl.optimize_index('ceshi_index','full');
--最後一個問題,就是用戶輸入的關鍵字也需要進行分詞,因爲前面分詞圖可以看到,詞被分成一塊一塊,如果用戶輸入的詞不拆分,有可能查不出來數據。(最後這一步驟的實現不理解)
--首先需要先創建一個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 p_split_chinese('我今天去上學,我到底是去還是不去呢') from dual;
F_SPLIT_CHINESE('重慶天府')
--最後,通過這些步驟,我們就可以根據jdbc來實現功能了。
-------------------------------------------------------------
select t.*, t.rowid from dr$ceshi_index$i t
insert into ceshi values ('222','我愛北京天安門')
select * from ceshi c where contains(c.name,p_split_chinese('江蘇省無錫市國家軟件園')) > 0
exec ctx_ddl.sync_index('ceshi_index'); --新增的數據之後必須執行該命令
select p_split_chinese('江蘇省無錫市國家軟件園') from dual;
--江蘇省 無錫 市 國家 軟件 園
select substr('or 江蘇省 or 無錫 or 市 or 國家 or 軟件 or 園',4) from dual;
----------------------------------------------------------------
--需要添加過濾關鍵詞時首先將索引刪除,然後在過濾詞組中添加過濾詞,之後重新創建索引:
drop index ceshi_INDEX force;
exec ctx_ddl.add_stopword('my_stoplist','有限公司');
create index ceshi_INDEX on ceshi(name) indextype is CTXSYS.CONTEXT parameters('lexer my_lexer stoplist my_stoplist');
exec ctx_ddl.sync_index('ceshi_index'); --新增的數據之後必須執行該命令
--查看過濾詞組中用哪些詞被過濾屏蔽:
SELECT * FROM CTX_USER_STOPLISTS;
SELECT * FROM CTX_USER_STOPWORDS;
--刪除過濾詞組中的某個過濾詞
exec ctx_ddl.remove_stopword('my_stoplist','道');
commit;