Oracle 从7.3 开始支持全文检索,即用户可以使用Oracle 服务器的上下文(ConText )选项完成基于文本的查询。具体可以采用通配符查找、模糊匹配、相关分类、近似查找、条件加权和词意扩充等方法。在Oracle8.0.x 中称为ConText ;在Oracle8i 中称为interMedia Text ; Oracle9i 中称为Oracle Text 。
http://blog.csdn.net/fengzhu1008/archive/2009/01/15/3784853.aspx
Oracle 全文索引
前言 :
Oracle 从7.3 开始支持全文检索,即用户可以使用Oracle 服务器的上下文(ConText )选项完成基于文本的查询。具体可以采用通配符查找、模糊匹配、相关分类、近似查找、条件加权和词意扩充等方法。在Oracle8.0.x 中称为ConText ;在Oracle8i 中称为interMedia Text ; Oracle9i 中称为Oracle Text 。
Oracle Text 是9i 标准版和企业版的一部分。Oracle9i 将全文检索功能做为内置功能提供给用户,使得用户在创建数据库实例时自动安装全文检索。Oracle Text 的应用领域有很多:
l 搜索文本 :需要快捷有效搜索文本数据的应用程序。
l 管理多种文档:允许搜索各种混和文档格式的应用程序, 包括ord,excel,lotus 等。
l 从多种数据源中检索文本:不仅来自Oracle 数据库中的文本数据, 而且可以来自Internet 和文件系统的文本数据。
l 搜索XML 应用程序。
1 、搜索文本
不使用 Oracle text 功能 , 也有很多方法可以在 Oracle 数据库中搜索文本 . 可以使用标准的 INSTR 函数和 LIKE 操作符实现 .
SELECT *
FROM mytext
WHERE INSTR (thetext, 'Oracle') > 0;
SELECT *
FROM mytext
WHERE thetext LIKE '%Oracle%';
有很多时候,使用 instr 和 like 是很理想的,特别是搜索仅跨越很小的表的时候。然而通过这些文本定位的方法将导致全表扫描 , 对资源来说消耗比较昂贵,而且实现的搜索功能也非常有限。
利用 Oracle Text ,你可以回答如“在存在单词 ’Oracle’ 的行同时存在单词 ’Corporation’ 而且两单词间距不超过 10 个单词的文本,查询含有单词 ’Oracle’ 或者单词 ’california’ 的文本,并且将结果按准确度进行排序,含有词根 train 的文本”,以下的 sql 代码实现了如上功能,我们且不管这些语法是如何使用的:
DROP INDEX index mytext_idx; -- 丢弃索引 mytext_idx
/
CREATE INDEX mytext_idx
ON mytext( thetext )
INDEXTYPE is CTXSYS.CONTEXT; -- 创建 CONTEXT 类型索引 mytext_idx
/
SELECT id
FROM mytext
WHERE contains (thetext, 'near((Oracle,Corporation),10)') > 0; -- 发出 contains 查询
/
SELECT score (1), id
FROM mytext
WHERE contains (thetext, 'Oracle or california', 1) > 0
ORDER BY score (1) DESC
/
SELECT id
FROM mytext
WHERE contains (thetext, '$train') > 0;
2 、索引介绍
利用Oracle Text 对文档集合进行检索的时候,你必须先在你的文本列上建立索引。索引将文本打碎分成很多记号(token ),这些记号通常是用空格分开的一个个单词。
Oracle Text 应用的实现实际上就是一个 数据装载—> 索引数据—> 执行检索 的一个过程。
建立的Oracle Text 索引被称为域索引(domain index ),包括4 种索引类型:
CONTEXT 、CTXCAT 、CTXRULE 、CTXXPATH
依据你的应用程序和文本数据类型你可以任意选择一种。可以利用 Create Index 建立这 4 种索引。下面说一下这 4 种索引的使用环境:
l CONTEXT : 用于对含有大量连续文本数据进行检索。支持 word 、 html 、 xml 、 text 等很多数据格式。支持中文字符集,支持分区索引,唯一支持并行创建索引( Parallel indexing )的索引类型。对表进行 DML 操作后,并不会自动同步索引。需要手工同步索引。 查询操作符: CONTAINS 。
l CTXCAT : 当使用混合查询语句的时候可以带来很好的效率。适合于查询较小的具有一定结构的文本段。具有事务性,当更新主表的时候自动同步索引。 The CTXCAT index does not support table and index partitioning, documents services (highlighting, markup, themes, and gists) or query services (explain, query feedback, and browse words.) 。 查询操作符: CATSEARCH
l CTXRULE : Use to build a document classification application. You create this index on a table of queries, where each query has a classification. Single documents (plain text, HTML, or XML) can be classified by using the MATCHES operator 。 查询操作符: MATCHES 。
l CTXXPATH : Create this index when you need to speed up ExistsNode() queries on an XMLType column 。 Can only create this index on XMLType column. 。 查询操作符:无。
在以上 4 种索引中,最常用的就是 CONTEXT 索引,使用 CONTAINS 操作符进行查询。 Oracle Text 索引将文本打碎分成很多的记号( token ),例如文本‘ I Love www.itpub.net ’将会被分成: I , LOVE , WWW , ITPUB , NET 这样的记号( token )。
Oracle Text CONTEXT 索引是反向索引( inverted index )。每个记号 ( token )都映射着包含它自己的文本位置。在索引建立过程中,单词 Cat 会包括如下的条目入口:
Cat row1,row2,row3
表示 Cat 在行 row1 、 row2 、 row3 都出现过,这样通过查找单词所对应的行的 rowid 就可以迅速找到文本记录。
在索引建好后,我们可以在该用户下查到 Oracle 自动产生了以下几个表:(假设索引名为 myindex ): DR$myindex$I 、 DR$myindex$K 、 DR$myindex$R 、 DR$myindex$N 其中以 I 表最重要,默认情况下全文索引是不区分大小写。
赋权限:
grant resource,dba,connect,ctxapp to username;
grant execute on ctxsys.ctx_ddl to username; -- 用于创建同步和优化索引的存储过程。
说明: ctxapp 用于用户建立 Oracle Text 索引 。
3 、 CONTEXT 索引
语法:
CREATE INDEX [schema.]index on [schema.]table(column) INDEXTYPE IS ctxsys.context [ONLINE]
LOCAL [(PARTITION [partition] [PARAMETERS('paramstring')]
[, PARTITION [partition] [PARAMETERS('paramstring')]])]
[PARAMETERS(paramstring)] [PARALLEL n] [UNUSABLE];
数据库用创建和插入这些索引的方法叫做索引管道( index Pipeline )。根据不同的参数构建索引,可以应用于很多实际环境。
类别 | 描述 |
Datastore | 从哪里得到数据? |
Filter | 将数据转换成文本 |
Lexer | 正在索引什么语言? |
Wordlist | 应该如何展开茎干和模糊查询 |
Storage | 如何存储索引 |
Stop List | 什么单词或者主题不被索引? |
Section Group | 允许在区段内查询吗?如何定义文档区段。这把文档转换成普通文本 |
这些参数在建立 CONTEXT 索引过程中将按下图顺序对索引进程起作用。在本篇中提供一些简单 demo 会看到各个参数的作用。
建立索引时,系统默认文档存储在数据库的文本列中。如果不显示的指定索引参数,系统会自动探测文本语言 , 数据类型和文档格式。
CREATE INDEX myindex ON docs(text) INDEXTYPE IS CTXSYS.CONTEXT ;
如上命令在表 docs 的 text 列上建立了一个默认参数的 CONTEXT 类型索引 myindex ,系统默认:
l 文本存储在数据库中。可以是 CLOB, BLOB, BFILE, VARCHAR2, or CHAR 类型的文本数据。
l 文本列语言是数据库建立时的默认的字符集。
l 使用数据库默认的终止目录 stoplist.stoplist 记录存在于文本列中但不对其索引的词。
l 允许模糊查询。
索引参数
Oracle Text 索引文档时所使用的主要参数如下:
1) 数据存储逻辑(DATASTORE) 搜索表的所有行,并读取列中的数据。通常,这只是列数据,但有些数据存储使用列数据作为文档数据的指针。例如,URL_DATASTORE 将列数据作为 URL 使用。
2) 过滤器(FILTER) 提取文档数据并将其转换为文本表示方式。存储二进制文档 ( 如 Word 或 Acrobat 文件) 时需要这样做。过滤器的输出不必是纯文本格式 -- 它可以是 XML 或 HTML 之类的文本格式。
3) 分段器(SECTIONER) 提取过滤器的输出信息,并将其转换为纯文本。包括 XML 和 HTML 在内的不同文本格式有不同的分段器。转换为纯文本涉及检测重要文档段标记、移去不可见的信息和文本重新格式化。
4) 词法分析器(Lexer) 提取分段器中的纯文本,并将其拆分为不连续的标记。既存在空白字符分隔语言使用的词法分析器,也存在分段复杂的亚洲语言使用的专门词法分析器。
5) 索引引擎(Indexing Engine) 提取词法分析 器中的所有标记、文档段在分段器中的偏移量以及被称为非索引字的低信息含量字列表,并构建反向索引。倒排索引存储标记和含有这些标记的文档。
DataStore : 指明你的文本是如何存储的。系统默认文档储存在数据库内的文本列( CHAR, VARCHAR, VARCHAR2, BLOB, CLOB, BFILE, or XMLType )中。 DataStore 对象在由过滤器处理之前从数据库中的列摘录文本。你要索引的文档可以来自多种数据源。
Datastore Type | Use When |
DIRECT_DATASTORE | Data is stored internally in the text column. Each row is indexed as a single document. |
MULTI_COLUMN_DATASTORE | Data is stored in a text table in more than one column. Columns are concatenated to create a virtual document, one per row. |
DETAIL_DATASTORE | Data is stored internally in the text column. Document consists of one or more rows stored in a text column in a detail table, with header information stored in a master table. |
FILE_DATASTORE | Data is stored externally in operating system files. Filenames are stored in the text column, one per row. |
NESTED_DATASTORE | Data is stored in a nested table. |
URL_DATASTORE | Data is stored externally in files located on an intranet or the Internet. Uniform Resource Locators (URLs) are stored in the text column. |
USER_DATASTORE | Documents are synthesized at index time by a user-defined stored procedure. |
说明: MULTI_COLUMN_DATASTORE 类型的 DATASTORE 必须在 ctxsys 用户下建立,在使用时还需要指明来源,如:
SQL> CONNECT CTXSYS/CTXSYS@SDH155
SQL>
EXEC CTX_DDL.CREATE_PREFERENCE(‘mymds’,’MULTI_COLUMN_DATASTORE’);
SQL> EXEC ctx_ddl.set_attibute('mymds', 'columns', 'name, address');
SQL>create index doc_idx on docs(doc) indextype is ctxsys.context
parameters(‘DATASTORE ctxsys.mymds ’);
Filter 过滤: 一旦汇编了文档,它就沿管道传递。接下来这个阶段是过滤( Filter ) . 如果文档是一种外来格式,就将它转换为可读取的文本,以便进行索引。默认是 NULL_FILTER ,它简单的直接传递文档,不作任何修改。
通常我们使用 NULL_FILTER 过滤普通文本和 HTML 文档。下面是一个索引 HTML 文档的例子:
CREATE INDEX myindex
ON docs(htmlfile)
INDEXTYPE IS ctxsys.CONTEXT
PARAMETERS ('filter ctxsys.null_filter section group ctxsys.html_section_group');
我们使用 null_filter 过滤类和 ctxsys 用户自带的 html_section_group 区段组类。我们会在后面马上介绍区段组( Section Groups )的概念。
Section Groups 区分组: 区分组( Section Groups )是与 interMedia 一起使用 XML 的关键。这些组处理 XML (或者 HTML )文档,输出两个数据流,即区段界限和文本内容。默认是 NULL_SECTION_GROUP, 它简单的直接传递文本,不执行任何修改和处理。 HTML_SECTION_GROUP 是专门用来处理 HTML 文档的。
Storage 类: Storage( 存储空间 ) 组的类只含有 BASIC_STORAGE. 默认情况下, BASIC_STORAGE 对象的属性是空的。我们通常需要定制自己的 STORAGE 类,来控制索引的存储参数以及存储空间。建立全文索引的时候我们通常会考虑表段 dr$indexname$I ,, dr$indexname$R ,索引段 dr$indexname$X 的空间分配。
类型 | 描述 |
BASIC_STORAGE | 为 CONTEXT 索引指定默认的存储参数 |
BASIC_STORAGE 有如下参数
<td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 2.25pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 2.25pt; PADDING-BOTTOM: 2.25pt; BORDER-LEFT: windowtext 1pt solid; PADDING-TOP: 2.25pt; B 属性 | 属性值 |
i_table_clause | Parameter clause for dr$indexname$I table creation. Specify storage and tablespace clauses to add to the end of the internal CREATE TABLE statement. The I table is the index data table. |
k_table_clause | Parameter clause for dr$indexname$K table creation. Specify storage and tablespace clauses to add to the end of the internal CREATE TABLE statement. The K table is the keymap table. |
r_table_clause | Parameter clause for dr$indexname$R table creation. Specify storage and tablespace clauses to add to the end of the internal CREATE TABLE statement. The R table is the rowid table. The default clause is: 'LOB(DATA) STORE AS (CACHE)' |