oracle全文检索Oracle一直致力于全文检索技术的研究,当Oracle9iRlease2发布之时,Oracle数据库的全文检索技术已经非常完美,OracleText使Oracle9i具备了强大的文本检索能力和智能化的文本管理能力。OracleText是Oracle9i采用的新名称,在Oracle8/8i中它被称作OracleinterMediaText,在Oracle8以前它的名称是OracleConTextCartridge。使用Oracle9i和OracleText,可以方便而有效地利用标准的SQL工具来构建基于文本的新的开发工具或对现有应用程序进行扩展。应用程序开发人员可以在任何使用文本的Oracle数据库应用程序中充分利用OracleText搜索,应用范围可以是现有应用程序中可搜索的注释字段,也可是实现涉及多种文档格式和复杂搜索标准的大型文档管理系统。OracleText支持Oracle数据库所支持的大多数语言的基本全文搜索功能。本文将介绍如何使用Oracle9i的全文检索技术来为自己的应用提供一个优秀的解决方案。1OracleText的体系架构下图是OracleText的体系架构。图1OracleText的体系架构以上面的体系架构图为基础,OracleText索引文档时所使用的主要逻辑步骤如下:(1)数据存储逻辑搜索表的所有行,并读取列中的数据。通常,这只是列数据,但有些数据存储使用列数据作为文档数据的指针。例如,URL_DATASTORE将列数据作为URL使用。(2)过滤器提取文档数据并将其转换为文本表示方式。存储二进制文档(如Word或Acrobat文件)时需要这样做。过滤器的输出不必是纯文本格式--它可以是XML或HTML之类的文本格式。(3)分段器提取过滤器的输出信息,并将其转换为纯文本。包括XML和HTML在内的不同文本格式有不同的分段器。转换为纯文本涉及检测重要文档段标记、移去不可见的信息和文本重新格式化。(4)词法分析器提取分段器中的纯文本,并将其拆分为不连续的标记。既存在空白字符分隔语言使用的词法分析器,也存在分段复杂的亚洲语言使用的专门词法分析器。(5)索引引擎提取词法分析器中的所有标记、文档段在分段器中的偏移量以及被称为非索引字的低信息含量字列表,并构建反向索引。倒排索引存储标记和含有这些标记的文档。2简单的示例这里先给出一个简单示例说利用OracleText实现全文检索的方法与步骤,在后面在进行具体的说明。Orcale9i提供了OracleTextManager可以简化许多工作,所有在OracleTextManager中完成的工作,都可以在通过PL/SQL来实现。要使用OracleText,必须具有CTXAPP角色或者是CTXSYS用户。OracleText为系统管理员提供CTXSYS用户,为应用程序开发人员提供CTXAPP角色。CTXSYS用户可执行以下任务:启动OracleText服务器,执行CTXAPP角色的所有任务。具有CTXAPP角色的用户可执行以下任务:创建索引,管理OracleText数据字典,包括创建和删除首选项,进行OracleText查询,使用OracleTextPL/SQL程序包。使用OracleText的步骤:(1)创建表来保存某些文档。该示例使用一个主关键字列来标识每个文档,使用一个小的VARCHAR2列来保存每个文档。CREATETABLEdocs(idNUMBERPRIMARYKEY,textVACHAR2(80));(2)将两个示例文档置入该表:INSERTINTOdocsVALUES(1,'thefirstdoc');INSERTINTOdocsVALUES(2,'theseconddoc');COMMIT;(3)使用OracleTextManager来创建和修改首选项,首选项将与索引相关联。(4)使用OracleTextManager创建文本索引。另外,可以输入以下使用默认首选项的SQL语句:CREATEINDEXdoc_indexONdocs(text)INDEXTYPEISCTXSYS.CONTEXT;(5)使用CONTAINS函数,发出基于内容的文档查询。例如:SELECTidFROMdocsWHERECONTAINS(text,'first')0;这将在文本列包含单词first(即文档1)的docs中查找所有行。语句中的0部分是有效的OracleSQL所必需的,OracleSQL不支持函数的布尔返回值。以上只是一个简单的示例,旨在给出使用OracleText建立全文索引的完整步骤,归纳起来如下:(1)建表并装载文本(包含带有需要检索的文本字段)(2)配置索引(3)建立索引(4)发出查询(5)索引维护:同步与优化(将在后面介绍)3文本装载要实现文本的全文检索首先必须把正确的文本加载到数据库表中,默认的建立索引行为要求将文档装载在文本列中,尽管可以用其它方式(包括文件系统和URL形式)存储文档(在数据存储选项进行设置)。默认情况下,系统应该将文档装载在文本列中。文本列可以是VARCHAR2、CLOB、BLOB、CHAR或BFILE。注意,只有在将Oracle7系统移植到Oracle8的情况下才支持用LONG和LONGRAW这两个相反的列类型存储文本。不能为列类型NCLOB、DATE和NUMBER建立索引。关于文档格式,因为系统能为包括HTML、PDF、MicrosoftWord和纯文本在内的大多数文档格式建立索引,可以将其中的任何文档类型装载到文本列中(在过滤器选项中设置)。有关所支持的文档格式的详细信息,可以参阅OracleTextUser'sGuideandReference中的附录SupportedFilterFormats。装载方法主要有以下几种:(1)SQLINSERT语句(2)ctxload可执行文件(3)SQL*Loader(4)从BFILE中装载LOB的DBMS_LOB.LOADFROMFILE()PL/SQL过程(5)OracleCallInterface4为文本建立索引文本装入文本列后,就可以创建OracleText索引。文档以许多不同方案、格式和语言存储。因此,每个OracleText索引有许多需要设置的选项,以针对特定情况配置索引。创建索引时,OracleText可使用若干个默认值,但在大多数情况下要求用户通过指定首选项来配置索引。每个索引的许多选项组成功能组,称为类,每个类集中体现配置的某一方面,可以认为这些类就是与文档数据库有关的一些问题。例如:数据存储、过滤器、词法分析器、相关词表、存储等。每个类具有许多预定义的行为,称之为对象。每个对象是类问题可能具有的答案,并且大多数对象都包含有属性。通过属性来定制对象,从而使对索引的配置更加多变以适应于不同的应用。(1)存储(Storage)类存储类指定构成OracleText索引的数据库表和索引的表空间参数和创建参数。它仅有一个基本对象: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)文档段组(SectionGroup)类文档段组是用于指定一组文档段的对象。必须先定义文档段,然后才能使用索引通过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)索引集(IndexSet)索引集是一个或多个Oracle索引(不是OracleText索引)的集合,用于创建CTXCAT类型的OracleText索引,只有一个基本对象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_FILTERINSO、NULL_FILTER、PROCEDURE_FILTER、USER_FILTER。(8)非索引字表(Stoplist)类非索引字表类是用以指定一组不编入索引的单词(称为非索引字)。有两个基本对象:BASIC_STOPLIST(一种语言中的所有非索引字)、MULTI_STOPLIST(包含多种语言中的非索引字的多语言非索引字表)。5查询建立了索引,就可以使用SELECT语句中的CONTAINS运算符发出文本查询。使用CONTAINS可以进行两种查询:单词查询和ABOUT查询。5.1词查询示例词查询是对输入到CONTAINS运算符中单引号间的精确单词或短语的查询。在以下示例中,我们将查找文本列中包含oracle一词的所有文档。每行的分值由使用标签1的SCORE运算符选定:SELECTSCORE(1)titlefromnewsWHERECONTAINS(text,'oracle',1)0;在查询表达式中,可以使用AND和OR等文本运算符来获取不同结果。还可以将结构性谓词添加到WHERE子句中。可以使用count(*)、CTX_QUERY.COUNT_HITS或CTX_QUERY.EXPLAIN来计算查询的命中(匹配)数目。5.2ABOUT查询示例在所有语言中,ABOUT查询增加了某查询所返回的相关文档的数目。在英语中,ABOUT查询可以使用索引的主题词组件,该组件在默认情况下创建。这样,运算符将根据查询的概念返回文档,而不是仅依据所指定的精确单词或短语。例如,以下查询将查找文本列中关于主题politics的所有文档,而不是仅包含politics一词的文档:SELECTSCORE(1)titlefromnewsWHERECONTAINS(text,'about(politics)',1)0;6显示满足查询条件的文档通常,通过使用OracleText查询应用程序,用户可查看查询所返回的文档。用户从命中列表中选择一个文档,然后应用程序以某种形式显示该文档。通过OracleText,可以用不同的方式再现文档。例如,可以