Oracle一直致力于全文检索技术的研究,当Oracle9i Rlease2发布之时,Oracle数据库的全文检索技术已经非常完美,Oracle Text使Oracle9i具备了强大的文本检索能力和智能化的文本管理能力。Oracle Text是Oracle9i采用的新名称,在Oracle8/8i中它被称作Oracle interMedia Text。使用Oracle Text,可以方便而有效地利用标准的SQL工具来构建基于文本的新的开发工具或对现有应用程序进行扩展。应用程序开发人员可以在任何使用文本的Oracle数据库应用程序中充分利用Oracle Text搜索,应用范围可以是现有应用程序中可搜索的注释字段,也可是实现涉及多种文档格式和复杂搜索标准的大型文档管理系统。Oracle Text支持Oracle数据库所支持的大多数语言的基本全文搜索功能。
虽然大多数大型数据库都支持全文检索,但Oracle在这方面无疑是最出色的。Oracle能搜索多种格式的文档,如Word,Execl,PowerPoint,Html,PDF等等
。
1 Oracle Text
的体系架构
下图是
Oracle Text
的体系架构:
图
1 Oracle Text
的体系架构
Oracle Text
索引文档时所使用的主要逻辑步骤如下:
(
1
)数据存储逻辑搜索表的所有行,并读取列中的数据。通常,这只是列数据,但有些数据存储使用列数据作为文档数据的指针。例如,
URL_DATASTORE
将列数据作为
URL
使用。如果对本地文件进行检索,只要指定
DATASTORE
中
FILE_DATASTORE
参数为文件的路径即可。
(
2
)过滤器提取文档数据并将其转换为文本表示方式。存储二进制文档
(
如
Word
或
Acrobat
文件
)
时需要这样做。过滤器的输出不必是纯文本格式
--
它可以是
XML
或
HTML
之类的文本格式。
(
3
)分段器提取过滤器的输出信息,并将其转换为纯文本。包括
XML
和
HTML
在内的不同文本格式有不同的分段器。转换为纯文本涉及检测重要文档段标记、移去不可见的信息和文本重新格式化。
(
4
)词法分析器提取分段器中的纯文本,并将其拆分为不连续的标记。既存在空白字符分隔语言使用的词法分析器,也存在分段复杂的亚洲语言使用的专门词法分析器。
(
5
)索引引擎提取词法分析器中的所有标记、文档段在分段器中的偏移量以及被称为非索引字的低信息含量字列表,并构建反向索引。倒排索引存储标记和含有这些标记的文档。
归纳起来如下:
(
1
)建表并装载文本(包含带有需要检索的文本字段)
(
2
)配置索引
(
3
)建立索引
(
4
)发出查询
(
5
)索引维护:同步与优化(将在后面介绍)
u
文本装载
要实现文本的全文检索首先必须把正确的文本加载到数据库表中,默认的建立索引行为要求将文档装载在文本列中,尽管可以用其它方式
(
包括文件系统和
URL
形式
)
存储文档
(
在
"
数据存储
"
选项进行设置
)
。默认情况下,系统应该将文档装载在文本列中。文本列可以是
VARCHAR2
、
CLOB
、
BLOB
、
CHAR
或
BFILE
。注意,只有在将
Oracle7
系统移植到
Oracle8
的情况下才支持用
LONG
和
LONG RAW
这两个相反的列类型存储文本。不能为列类型
NCLOB
、
DATE
和
NUMBER
建立索引。
关于文档格式,因为系统能为包括
HTML
、
PDF
、
Microsoft Word
和纯文本在内的大多数文档格式建立索引,可以将其中的任何文档类型装载到文本列中
(
在
"
过滤器
"
选项中设置
)
。有关所支持的文档格式的详细信息,可以参阅
Oracle Text User's Guide and Reference
中的附录
"Supported Filter Formats"
。
装载方法主要有以下几种:
(
1
)
SQL INSERT
语句
(
2
)
ctxload
可执行文件
(
3
)
SQL*Loader
(
4
)从
BFILE
中装载
LOB
的
DBMS_LOB.LOADFROMFILE() PL/SQL
过程
(
5
)
Oracle Call Interface
u
建立索引
文本装入文本列后,就可以创建
Oracle Text
索引。文档以许多不同方案、格式和语言存储。因此,每个
Oracle Text
索引有许多需要设置的选项,以针对特定情况配置索引。创建索引时,
Oracle Text
可使用若干个默认值,但在大多数情况下要求用户通过指定首选项来配置索引。
每个索引的许多选项组成功能组,称为
"
类
"
,每个类集中体现配置的某一方面,可以认为这些类就是与文档数据库有关的一些问题。例如:数据存储、过滤器、词法分析器、相关词表、存储等。
每个类具有许多预定义的行为,称之为对象。每个对象是类问题可能具有的答案,并且大多数对象都包含有属性。通过属性来定制对象,从而使对索引的配置更加多变以适应于不同的应用。
(
1
)存储(
Storage
)类
存储类指定构成
Oracle Text
索引的数据库表和索引的表空间参数和创建参数。它仅有一个基本对象:
BASIC_STORAGE
,其属性包括:
I_Index_Clause
、
I_Table_Clause
、
K_Table_Clause
、
N_Table_Clause
、
P_Table_Clause
、
R_Table_Clause
。
(
2
)数据存储(
Datastore
)类
数据存储:关于列中存储文本的位置和其他信息。默认情况下,文本直接存储到列中,表中的每行都表示一个单独的完整文档。其他数据存储位置包括存储在单独文件中或以其
URL
标识的
Web
页上。七个基本对象包括:
Default_Datastore
、
Detail_Datastore
、
Direct_Datastore
、
File_Datastore
、
Multi_Column_Datastore
、
URL_Datastore
、
User_Datastore
,。
(
3
)文档段组(
Section Group
)类
文档段组是用于指定一组文档段的对象。必须先定义文档段,然后才能使用索引通过
WITHIN
运算符在文档段内进行查询。文档段定义为文档段组的一部分。包含七个基本对象:
AUTO_SECTION_GROUP
、
BASIC_SECTION_GROUP
、
HTML_SECTION_GROUP
、
NEWS_SECTION_GROUP
、
NULL_SECTION_GROUP
、
XML_SECTION_GROUP
、
PATH_SECTION_GROUP
。
(
4
)相关词表(
Wordlist
)类
相关词表标识用于索引的词干和模糊匹配查询选项的语言,只有一个基本对象
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
索引
)
的集合,用于创建
CTXCAT
类型的
Oracle Text
索引,只有一个基本对象
BASIC_INDEX_SET
。
(
6
)词法分析器(
Lexer
)类
词法分析器类标识文本使用的语言,还确定在文本中如何标识标记。默认的词法分析器是英语或其他西欧语言,用空格、标准标点和非字母数字字符标识标记,同时禁用大小写。包含
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
运算符发出文本查询。使用
CONTAINS
可以进行两种查询:单词查询和
ABOUT
查询。
5
.
1
词查询示例
词查询是对输入到
CONTAINS
运算符中单引号间的精确单词或短语的查询。在以下示例中,我们将查找文本列中包含
oracle
一词的所有文档。每行的分值由使用标签
1
的
SCORE
运算符选定:
SELECT SCORE(1) title from news WHERE CONTAINS(text, 'oracle', 1) > 0;
在查询表达式中,可以使用
AND
和
OR
等文本运算符来获取不同结果。还可以将结构性谓词添加到
WHERE
子句中。可以使用
count(*)
、
CTX_QUERY.COUNT_HITS
或
CTX_QUERY.EXPLAIN
来计算查询的命中
(
匹配
)
数目。
5
.
2 ABOUT
查询示例
在所有语言中,
ABOUT
查询增加了某查询所返回的相关文档的数目。在英语中,
ABOUT
查询可以使用索引的主题词组件,该组件在默认情况下创建。这样,运算符将根据查询的概念返回文档,而不是仅依据所指定的精确单词或短语。例如,以下查询将查找文本列中关于主题
politics
的所有文档,而不是仅包含
politics
一词的文档:
SELECT SCORE(1) title from news WHERE CONTAINS(text, 'about(politics)', 1) > 0;
索引维护
索引建好后,如果表中的数据发生变化,比如增加或修改了记录,怎么办?由于对表所发生的任何
DML
语句,都不会自动修改索引,因此,必须定时同步
(sync)
和优化
(optimize)
索引,以正确反映数据的变化。
在索引建好后,可以在该用户下查到
Oracle
自动产生了以下几个表:(假设索引名为
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;
查询结果在此省略。可以看到,该表中保存的其实就是
Oracle
分析你的文档后,生成的
term
记录在这里,包括
term
出现的位置、次数、
hash
值等。当文档的内容改变后,可以想见这个
I
表的内容也应该相应改变,才能保证
Oracle
在做全文检索时正确检索到内容(因为所谓全文检索,其实核心就是查询这个表)。那么如何维护该表的内容,不能每次数据改变都重新建立索引,这就要用到
sync
和
optimize
了。
同步(
sync
):将新的
term
保存到
I
表;
优化(
optimize
):清除
I
表的垃圾,主要是将已经被删除的
term
从
I
表删除。