Oracle Text(全文檢索索引)
查看資料庫教程相關的資訊select * from nls_database_parameters
1、簡單應用
1.1如果要使用全文檢索索引,當前ORACLE使用者必須具有CTXAPP角色
--建立一個使用者
--create user textsearch identified by textsearch;
/**
賦予使用者三個角色,其中有一個為CTXAPP角色,
以便該使用者可以使用與全文檢索索引相關的PROCEDURE
*/
grant connect,resource,ctxapp to textsearch;
/
使用建立的使用者登入
SQL> conn textsearch
輸入口令: **********
已串連。
1.2建立要進行全文檢索索引的資料表,準備資料
--drop table textdemo;
create table textdemo(
id number not null primary key,
book_author varchar2(20),--作者
publish_time date,--發布日期
title varchar2(400),--標題
book_abstract varchar2(2000),--摘要
path varchar2(200)--路徑
);
commit;
insert into textdemo values(1,'宮琦峻',to_date('2008-10-07','yyyy-mm-dd'),'移動城堡','故事發生在19世紀末的歐洲,善良可愛的蘇菲被惡毒的女巫施下魔咒,從18歲的女孩變成90歲的婆婆,孤單無助的她無意中走入鎮外的移動城堡,據說它的主人哈爾以吸取女孩的靈魂為樂,但是事情並沒有人們傳說的那麼可怕,性情古怪的哈爾居然收留了蘇菲,兩個人在四腳的移動城堡中開始了奇妙的共同生活,一段交織了愛與痛、樂與悲的愛情故事在戰火中悄悄展開','E:textsearchmoveingcastle.doc');
insert into textdemo values(2,'莫·貝克曼貝托夫',to_date('2008-10-07','yyyy-mm-dd'),'子彈轉彎','這部由俄羅斯導演提莫·貝克曼貝托夫執導的影片自6月末在北美上映以來,已經在全球取得了超過3億美元的票房收入。在亞洲上映後也先後拿下日本、韓國等地的票房冠軍寶座。雖然不少網友在此之前也相繼通過各種渠道接觸到本片,但相信影片憑著在大銀幕上呈現出的超酷的視聽效果,依然能夠吸引大量影迷前往影院捧場。','E:textsearchcatch.pdf');
insert into textdemo values(3,'袁泉',to_date('2008-10-07','yyyy-mm-dd'),'主演吳彥祖和袁泉現身','電影《如夢》在上海同樂坊拍攝,主演吳彥祖和袁泉現身。由於是深夜拍攝,所以周圍並沒有過多的fans注意到,給了劇組一個很清淨的拍攝環境,站在街頭的袁泉低著頭,在寒冷的夜裡看上去還真有些像女鬼,令人毛骨悚然。','E:textsearchdream.txt');
commit;
1.3在摘要欄位上建立索引
/*
*建立索引,使用預設的參數
*/
--drop index demo_abstract;
create index demo_abstract on textdemo(book_abstract)
indextype is ctxsys.context
--parameters('datastore ctxsys.default_datastore filter ctxsys.auto_filter ')
;
commit;
(1) 建表並裝載文本。
(2) 建立索引。如果想配置Oracle索引,可以在建立索引前進行配置,如:改變詞法分析器。可以下面SQL語句查看Oracle全文檢索索引的配置:
SELECT * FROM CTX_PREFERENCES;
(3) SQL查詢。
(4) 索引維護:同步與最佳化。
授權
執行全文的使用者必須具有 CTXAPP角色 或 CTXSYS使用者,以及 CTX_DDL包 執行許可權。
(1) 用 SYS使用者 授予 SCOTT 使用者 CTXAPP 角色,命令如下:
GRANT CTXAPP TO SCOTT;
(2) 用 CTXSYS 使用者 給 SCOTT 使用者 授權 CTX_DDL 包的執行許可權,命令如下:
GRANT EXECUTE ON CTX_DLL TO SCOTT;
建立表、添加記錄和索引
以下的SQL語句和 JOB都在 SCOTT 使用者下執行。首先,執行以下 SQL 陳述式,建立表 DOCS,並插入兩條記錄,提交後建立索引 doc_index。
DROP TABLE DOCS;CREATE TABLE DOCS (id NUMBER PRIMARY KEY,text VARCHAR2(80)); INSERT INTO docs VALUES (1,'the first doc');INSERT INTO docs VALUES (2,'the second doc');COMMIT; CREATE INDEX doc_index ON DOCS(text) INDEXTYPE IS CTXSYS.CONTEXT;
然後,執行查詢,C#代碼如下:
string connStr="Data Source=ora9; uid=scott; pwd=tiger; unicode=true"; string sqlStr = "SELECT ID FROM DOCS WHERE CONTAINS(TEXT,'%FIRST%')>0";OracleDataAdapter da = new OracleDataAdapter(sqlStr, connStr);DataTable dt = new DataTable();da.Fill(dt);Response.Write(dt.Rows[0][0].ToString());
同步和最佳化
當表 DOCS 發生變化(插入,刪除)後,索引必須能反應這個變化,這就需要對索引進行同步和最佳化。Oracle提供 ctx server 完成同步和最佳化,也可以用以下的job來完成。
同步sync
將新的term儲存到I表。
create or replace procedure sync isbeginexecute immediate 'alter index doc_index rebuild online' ||' parameters ( ''sync'' )';execute immediate 'alter index doc_index rebuild online' ||' parameters ( ''optimize full maxtime unlimited'' )';end sync;
最佳化
清除I表的垃圾,將已經被刪除的term從I表刪除。
declarev_job number;beginDbms_Job.Submit(job => v_job,what => 'sync;',next_date => sysdate, /* default */interval => 'sysdate + 1/720' /* = 1 day / ( 24 hrs * 30 min) = 2 mins */);Dbms_Job.Run ( v_job );end;
其中,I表是 dr$doc_index$i 表。使用者建立索引後,Oracle會自動建立四個表,dr$doc_index$i、dr$doc_index$k、dr$doc_index$n和dr$doc_index$r。可以用SELECT語句查看此表的內容。
說明
(1) 本文是在Oracle 9i和10g環境下完全實現Oracle的全文檢索索引,包括建立表和索引,進行同步和最佳化;
(2) 進行全文檢索索引的SQL語句是"SELECT ID FROM DOCS WHERE CONTAINS(TEXT,'%FIRST%')>0";
(3) 其中,">0"是有效Oracle SQL所必需的,因為,Oracle SQL不支援函數的布爾傳回值;
(4) 其中,"CONTAINS(TEXT,'%FIRST%')>0",在Oracle 9i和10g與11g下有所不同;
(5) 最近做項目從Oracle 10g改成11g,在進行全文檢索索引時,Oracle 10g下的代碼,在11g下檢索不到結果;
(6) 初步認為,Oracle 9i和10g與11g的區別是,在9i和10g下,如果不使用“%”,則是精確檢索,否則是模糊檢索。而在11g下,則完全不用“%”;
(7) 另外,在9i和10g下,可以使用如:CONTAINS(TEXT,'%FIRST% AND %second%')>0,進行全文檢索索引,但在11g下,是不可以的,要分開寫,如:
CONTAINS(TEXT,'%FIRST%')>0 AND CONTAINS(TEXT,'%second%')>0;
(8) 感覺11g下的全文檢索索引更好