Oracle一直致力于全文檢索技術(shù)的研究,當Oracle9i Rlease2發(fā)布之時,Oracle數(shù)據(jù)庫的全文檢索技術(shù)已經(jīng)非常完美,Oracle Text使Oracle9i具備了強大的文本檢索能力和智能化的文本管理能力。Oracle Text是Oracle9i采用的新名稱,在Oracle8/8i中它被稱作Oracle interMedia Text。使用Oracle Text,可以方便而有效地利用標準的SQL工具來構(gòu)建基于文本的新的開發(fā)工具或?qū)ΜF(xiàn)有應(yīng)用程序進行擴展。應(yīng)用程序開發(fā)人員可以在任何使用文本的Oracle數(shù)據(jù)庫應(yīng)用程序中充分利用Oracle Text搜索,應(yīng)用范圍可以是現(xiàn)有應(yīng)用程序中可搜索的注釋字段,也可是實現(xiàn)涉及多種文檔格式和復雜搜索標準的大型文檔管理系統(tǒng)。Oracle Text支持Oracle數(shù)據(jù)庫所支持的大多數(shù)語言的基本全文搜索功能。
雖然大多數(shù)大型數(shù)據(jù)庫都支持全文檢索,但Oracle在這方面無疑是最出色的。Oracle能搜索多種格式的文檔,如Word,Execl,PowerPoint,Html,PDF等等
。
1 Oracle Text
的體系架構(gòu)
下圖是
Oracle Text
的體系架構(gòu):
圖
1 Oracle Text
的體系架構(gòu)
Oracle Text
索引文檔時所使用的主要邏輯步驟如下:
(
1
)數(shù)據(jù)存儲邏輯搜索表的所有行,并讀取列中的數(shù)據(jù)。通常,這只是列數(shù)據(jù),但有些數(shù)據(jù)存儲使用列數(shù)據(jù)作為文檔數(shù)據(jù)的指針。例如,
URL_DATASTORE
將列數(shù)據(jù)作為
URL
使用。如果對本地文件進行檢索,只要指定
DATASTORE
中
FILE_DATASTORE
參數(shù)為文件的路徑即可。
(
2
)過濾器提取文檔數(shù)據(jù)并將其轉(zhuǎn)換為文本表示方式。存儲二進制文檔
(
如
Word
或
Acrobat
文件
)
時需要這樣做。過濾器的輸出不必是純文本格式
--
它可以是
XML
或
HTML
之類的文本格式。
(
3
)分段器提取過濾器的輸出信息,并將其轉(zhuǎn)換為純文本。包括
XML
和
HTML
在內(nèi)的不同文本格式有不同的分段器。轉(zhuǎn)換為純文本涉及檢測重要文檔段標記、移去不可見的信息和文本重新格式化。
(
4
)詞法分析器提取分段器中的純文本,并將其拆分為不連續(xù)的標記。既存在空白字符分隔語言使用的詞法分析器,也存在分段復雜的亞洲語言使用的專門詞法分析器。
(
5
)索引引擎提取詞法分析器中的所有標記、文檔段在分段器中的偏移量以及被稱為非索引字的低信息含量字列表,并構(gòu)建反向索引。倒排索引存儲標記和含有這些標記的文檔。
歸納起來如下:
(
1
)建表并裝載文本(包含帶有需要檢索的文本字段)
(
2
)配置索引
(
3
)建立索引
(
4
)發(fā)出查詢
(
5
)索引維護:同步與優(yōu)化(將在后面介紹)
u
文本裝載
要實現(xiàn)文本的全文檢索首先必須把正確的文本加載到數(shù)據(jù)庫表中,默認的建立索引行為要求將文檔裝載在文本列中,盡管可以用其它方式
(
包括文件系統(tǒng)和
URL
形式
)
存儲文檔
(
在
"
數(shù)據(jù)存儲
"
選項進行設(shè)置
)
。默認情況下,系統(tǒng)應(yīng)該將文檔裝載在文本列中。文本列可以是
VARCHAR2
、
CLOB
、
BLOB
、
CHAR
或
BFILE
。注意,只有在將
Oracle7
系統(tǒng)移植到
Oracle8
的情況下才支持用
LONG
和
LONG RAW
這兩個相反的列類型存儲文本。不能為列類型
NCLOB
、
DATE
和
NUMBER
建立索引。
關(guān)于文檔格式,因為系統(tǒng)能為包括
HTML
、
PDF
、
Microsoft Word
和純文本在內(nèi)的大多數(shù)文檔格式建立索引,可以將其中的任何文檔類型裝載到文本列中
(
在
"
過濾器
"
選項中設(shè)置
)
。有關(guān)所支持的文檔格式的詳細信息,可以參閱
Oracle Text User's Guide and Reference
中的附錄
"Supported Filter Formats"
。
裝載方法主要有以下幾種:
(
1
)
SQL INSERT
語句
(
2
)
ctxload
可執(zhí)行文件
(
3
)
SQL*Loader
(
4
)從
BFILE
中裝載
LOB
的
DBMS_LOB.LOADFROMFILE() PL/SQL
過程
(
5
)
Oracle Call Interface
u
建立索引
文本裝入文本列后,就可以創(chuàng)建
Oracle Text
索引。文檔以許多不同方案、格式和語言存儲。因此,每個
Oracle Text
索引有許多需要設(shè)置的選項,以針對特定情況配置索引。創(chuàng)建索引時,
Oracle Text
可使用若干個默認值,但在大多數(shù)情況下要求用戶通過指定首選項來配置索引。
每個索引的許多選項組成功能組,稱為
"
類
"
,每個類集中體現(xiàn)配置的某一方面,可以認為這些類就是與文檔數(shù)據(jù)庫有關(guān)的一些問題。例如:數(shù)據(jù)存儲、過濾器、詞法分析器、相關(guān)詞表、存儲等。
每個類具有許多預(yù)定義的行為,稱之為對象。每個對象是類問題可能具有的答案,并且大多數(shù)對象都包含有屬性。通過屬性來定制對象,從而使對索引的配置更加多變以適應(yīng)于不同的應(yīng)用。
(
1
)存儲(
Storage
)類
存儲類指定構(gòu)成
Oracle Text
索引的數(shù)據(jù)庫表和索引的表空間參數(shù)和創(chuàng)建參數(shù)。它僅有一個基本對象:
BASIC_STORAGE
,其屬性包括:
I_Index_Clause
、
I_Table_Clause
、
K_Table_Clause
、
N_Table_Clause
、
P_Table_Clause
、
R_Table_Clause
。
(
2
)數(shù)據(jù)存儲(
Datastore
)類
數(shù)據(jù)存儲:關(guān)于列中存儲文本的位置和其他信息。默認情況下,文本直接存儲到列中,表中的每行都表示一個單獨的完整文檔。其他數(shù)據(jù)存儲位置包括存儲在單獨文件中或以其
URL
標識的
Web
頁上。七個基本對象包括:
Default_Datastore
、
Detail_Datastore
、
Direct_Datastore
、
File_Datastore
、
Multi_Column_Datastore
、
URL_Datastore
、
User_Datastore
,。
(
3
)文檔段組(
Section Group
)類
文檔段組是用于指定一組文檔段的對象。必須先定義文檔段,然后才能使用索引通過
WITHIN
運算符在文檔段內(nèi)進行查詢。文檔段定義為文檔段組的一部分。包含七個基本對象:
AUTO_SECTION_GROUP
、
BASIC_SECTION_GROUP
、
HTML_SECTION_GROUP
、
NEWS_SECTION_GROUP
、
NULL_SECTION_GROUP
、
XML_SECTION_GROUP
、
PATH_SECTION_GROUP
。
(
4
)相關(guān)詞表(
Wordlist
)類
相關(guān)詞表標識用于索引的詞干和模糊匹配查詢選項的語言,只有一個基本對象
BASIC_WORDLIST
,其屬性有:
Fuzzy_Match
、
Fuzzy_Numresults
、
Fuzzy_Score
、
Stemmer
、
Substring_Index
、
Wildcard_Maxterms
、
Prefix_Index
、
Prefix_Max_Length
、
Prefix_Min_Length
。
(
5
)索引集(
Index Set
)
索引集是一個或多個
Oracle
索引
(
不是
Oracle Text
索引
)
的集合,用于創(chuàng)建
CTXCAT
類型的
Oracle Text
索引,只有一個基本對象
BASIC_INDEX_SET
。
(
6
)詞法分析器(
Lexer
)類
詞法分析器類標識文本使用的語言,還確定在文本中如何標識標記。默認的詞法分析器是英語或其他西歐語言,用空格、標準標點和非字母數(shù)字字符標識標記,同時禁用大小寫。包含
8
個基本對象:
BASIC_LEXER
、
CHINESE_LEXER
、
CHINESE_VGRAM_LEXER
、
JAPANESE_LEXER
、
JAPANESE_VGRAM_LEXER
、
KOREAN_LEXER
、
KOREAN__MORPH_ LEXER
、
MULTI_LEXER
。
(
7
)過濾器(
Filter
)類
過濾器確定如何過濾文本以建立索引。可以使用過濾器對文字處理器處理的文檔、格式化的文檔、純文本和
HTML
文檔建立索引,包括
5
個基本對象:
CHARSET_FILTER
、
INSO_FILTER INSO
、
NULL_FILTER
、
PROCEDURE_FILTER
、
USER_FILTER
。
(
8
)非索引字表(
Stoplist
)類
非索引字表類是用以指定一組不編入索引的單詞
(
稱為非索引字
)
。有兩個基本對象:
BASIC_STOPLIST (
一種語言中的所有非索引字
)
、
MULTI_STOPLIST (
包含多種語言中的非索引字的多語言非索引字表
)
。
u
查詢
建立了索引,就可以使用
SELECT
語句中的
CONTAINS
運算符發(fā)出文本查詢。使用
CONTAINS
可以進行兩種查詢:單詞查詢和
ABOUT
查詢。
5
.
1
詞查詢示例
詞查詢是對輸入到
CONTAINS
運算符中單引號間的精確單詞或短語的查詢。在以下示例中,我們將查找文本列中包含
oracle
一詞的所有文檔。每行的分值由使用標簽
1
的
SCORE
運算符選定:
SELECT SCORE(1) title from news WHERE CONTAINS(text, 'oracle', 1) > 0;
在查詢表達式中,可以使用
AND
和
OR
等文本運算符來獲取不同結(jié)果。還可以將結(jié)構(gòu)性謂詞添加到
WHERE
子句中。可以使用
count(*)
、
CTX_QUERY.COUNT_HITS
或
CTX_QUERY.EXPLAIN
來計算查詢的命中
(
匹配
)
數(shù)目。
5
.
2 ABOUT
查詢示例
在所有語言中,
ABOUT
查詢增加了某查詢所返回的相關(guān)文檔的數(shù)目。在英語中,
ABOUT
查詢可以使用索引的主題詞組件,該組件在默認情況下創(chuàng)建。這樣,運算符將根據(jù)查詢的概念返回文檔,而不是僅依據(jù)所指定的精確單詞或短語。例如,以下查詢將查找文本列中關(guān)于主題
politics
的所有文檔,而不是僅包含
politics
一詞的文檔:
SELECT SCORE(1) title from news WHERE CONTAINS(text, 'about(politics)', 1) > 0;
索引維護
索引建好后,如果表中的數(shù)據(jù)發(fā)生變化,比如增加或修改了記錄,怎么辦?由于對表所發(fā)生的任何
DML
語句,都不會自動修改索引,因此,必須定時同步
(sync)
和優(yōu)化
(optimize)
索引,以正確反映數(shù)據(jù)的變化。
在索引建好后,可以在該用戶下查到
Oracle
自動產(chǎn)生了以下幾個表:(假設(shè)索引名為
myindex
):
DR$myindex$I
,
DR$myindex$K
,
DR$myindex$R
,
DR$myindex$N
其中以
I
表最重要,可以查詢一下該表:
select token_text, token_count from DR$ myindex $I where rownum<=20;
查詢結(jié)果在此省略。可以看到,該表中保存的其實就是
Oracle
分析你的文檔后,生成的
term
記錄在這里,包括
term
出現(xiàn)的位置、次數(shù)、
hash
值等。當文檔的內(nèi)容改變后,可以想見這個
I
表的內(nèi)容也應(yīng)該相應(yīng)改變,才能保證
Oracle
在做全文檢索時正確檢索到內(nèi)容(因為所謂全文檢索,其實核心就是查詢這個表)。那么如何維護該表的內(nèi)容,不能每次數(shù)據(jù)改變都重新建立索引,這就要用到
sync
和
optimize
了。
同步(
sync
):將新的
term
保存到
I
表;
優(yōu)化(
optimize
):清除
I
表的垃圾,主要是將已經(jīng)被刪除的
term
從
I
表刪除。