Oracle 11g Release 1 (11.1) Oracle 文本自定义 CONTEXT 索引的“偏好”
http://docs.oracle.com/cd/B28359_01/text.111/b28303/ind.htm#autoId58
本文内容
- 关于 Oracle 文本索引提供的存储过程
- 创建 Preferences
- 创建 Section Groups 搜索节
- 使用非索引字和非索引字列表
关于 Oracle 文本索引提供的存储过程
我们知道 Oracle 文本索引有四种类型:CONTEXT、CTXCAT、CTXRULE 和 CTXXPATH。其中 CTXXPATH 已标记废弃,在将来的 Oracle 版本会去掉。
默认情况,系统期望你的文本存储在文本列中。这样,你就可以使用没有显示指定任何“偏好(preferences)”的 CREATE INDEX 创建一个文本索引,作为一个可扩展的 CONTEXT 索引类型。系统会自动检测你的语言、文本列的数据类型、文档格式和相应索引偏好的设置。
所谓“偏好(preferences)”是你对文本索引的配置,类似 MS SQL Server 的“填充因子”。也就是说,在建立文本索引前,你可以先创建配置,再在创建文本索引时通过 parameter 子句使用。
若创建一个 Oracle 文本索引:
- 可选,确定你自定义索引的“偏好”、节组,或非索引字列表。下表描述这些索引类:
类 | 描述 |
Datastore | 你的文档如何存储 |
Filter | 文档如何转换成纯文本 |
Lexer | 索引的语言是什么 |
Wordlist | 模糊和词干查询如何扩展 |
Storage | 索引数据如何存储 |
Stop List | 什么样的词或主题不用索引 |
Section Group | 文档的节如何定义 |
- 可选,你自定义索引的“偏好”、节组,或非索引字列表。
- 用 CREATE INDEX 创建文本索引,命名你的索引,指定或不指定索引“偏好”。
更多 Oracle 文本索引要素,包括 Datastore、Filter 、Lexer 、Wordlist、Storage、Section Group 、Classifier、Cluster、Stoplists、System-Defined Preferences 和 System Parameters。
创建索引偏好
你可以自定义文本索引的“偏好(preferences)”。使用“偏好”来指定索引信息,例如你的文件存储在哪里,你的文档如何过滤。创建“偏好”,并设置其属性。
Datastore Examples
本小节给出 direct、multi-column、URL 和 file 数据存储的例子。
- 指定 DIRECT_DATASTORE
本例创建一个表,其 CLOB 列存储文本数据。向该表填充两条数据,并使用系统预定义的 preference CTXSYS.DEFAULT_DATASTORE 索引该表,它使用 DIRECT_DATASTORE preference 类型。
create table mytable(id number primary key, docs clob);
insert into mytable values(111555,'this text will be indexed');
insert into mytable values(111556,'this is a default datastore example');
commit;
create index myindex on mytable(docs)
indextype is ctxsys.context
parameters ('DATASTORE CTXSYS.DEFAULT_DATASTORE');
- 指定 MULTI_COLUMN_DATASTORE
本例在三个串联和索引的列上,创建一个名为 "my_multi" 多列数据存储的 preference。
begin
ctx_ddl.create_preference('my_multi', 'MULTI_COLUMN_DATASTORE');
ctx_ddl.set_attribute('my_multi', 'columns', 'column1, column2, column3');
end;
- 指定 URL_DATASTORE URL 数据存储
本例创建一个名为 "my_url" 的 URL_DATASTORE 偏好,并设置其属性 http_proxy、no_proxy 和 timeout。其中,timeout 属性为 300 秒。默认情况下,使用这些属性都没有设置。
begin
ctx_ddl.create_preference('my_url','URL_DATASTORE');
ctx_ddl.set_attribute('my_url','HTTP_PROXY','www-proxy.us.oracle.com');
ctx_ddl.set_attribute('my_url','NO_PROXY','us.oracle.com');
ctx_ddl.set_attribute('my_url','Timeout','300');
end;
- 指定 FILE_DATASTORE 文件数据存储
本例使用 FILE_DATASTORE 创建一个数据存储的偏好。该属性告诉系统,索引的文件位于操作系统。本例使用 CTX_DDL.SET_ATTRIBUTE 方法来设置 PATH 目录属性为 "/docs"。
begin
ctx_ddl.create_preference('mypref', 'FILE_DATASTORE');
ctx_ddl.set_attribute('mypref', 'PATH', '/docs');
end;
NULL_FILTER 示例: 索引 HTML 文档
如果你的文档集合完全是 HTML,那么,Oracle 建议在你的过滤偏好中使用 NULL_FILTER。
例如,若索引 HTML 文档集合,你可以指定 NULL_FILTER 和 HTML_SECTION_GROUP 如下所示:
create index myindex on docs(htmlfile) indextype is ctxsys.context
parameters('filter ctxsys.null_filter
section group ctxsys.html_section_group');
PROCEDURE_FILTER 示例
过滤存储过程 CTXSYS.NORMALIZE 的签名如下:
PROCEDURE NORMALIZE(id IN ROWID, charset IN VARCHAR2, input IN CLOB,
output IN OUT NOCOPY VARCHAR2);
你若使用这个存储过程过滤,建立过滤偏好如下:
begin
ctx_ddl.create_preference('myfilt', 'procedure_filter');
ctx_ddl.set_attribute('myfilt', 'procedure', 'normalize');
ctx_ddl.set_attribute('myfilt', 'input_type', 'clob');
ctx_ddl.set_attribute('myfilt', 'output_type', 'varchar2');
ctx_ddl.set_attribute('myfilt', 'rowid_parameter', 'TRUE');
ctx_ddl.set_attribute('myfilt', 'charset_parameter', 'TRUE');
end;
BASIC_LEXER 示例: 设置 Printjoin 字符
printjoin 字符是非字母数字字符,它们不能包含在索引中,因此,像网址这样的词可以作为网址来索引。
下面示例设置 printjoin 字符为“连字符”和“下划线”BASIC_LEXER:
begin
ctx_ddl.create_preference('mylex', 'BASIC_LEXER');
ctx_ddl.set_attribute('mylex', 'printjoins', '_-');
end;
若利用前面设置的 printjoins 字符创建索引,如下所示:
create index myindex on mytable ( docs )
indextype is ctxsys.context
parameters ( 'LEXER mylex' );
MULTI_LEXER 示例: 索引一个多语言表
你可以使用 MULTI_LEXER 偏好来索引一个包含不同语言的文档。例如,当你的文本列存储英语、德语和日语文档时,可以使用该偏好。
首先,创建一个有三列的多语言表,包括主键、语言和文本,如下所示:
create table globaldoc (
doc_id number primary key,
lang varchar2(3),
text clob
);
假设,该表大部分是英文文档,和一些德语、日语文档。若处理这三种语言,你必须为三种语言分别创建分词(子分词):
ctx_ddl.create_preference('english_lexer','basic_lexer');
ctx_ddl.set_attribute('english_lexer','index_themes','yes');
ctx_ddl.set_attribute('english_lexer','theme_language','english');
ctx_ddl.create_preference('german_lexer','basic_lexer');
ctx_ddl.set_attribute('german_lexer','composite','german');
ctx_ddl.set_attribute('german_lexer','mixed_case','yes');
ctx_ddl.set_attribute('german_lexer','alternate_spelling','german');
ctx_ddl.create_preference('japanese_lexer','japanese_vgram_lexer');
创建多分词偏好:
ctx_ddl.create_preference('global_lexer', 'multi_lexer');
因为,存储的文档大部分是英文,使用 CTX_DDL.ADD_SUB_LEXER 让英文分词为默认:
ctx_ddl.add_sub_lexer('global_lexer','default','english_lexer');
现在,用 CTX_DDL.ADD_SUB_LEXER 分别在德语和日语中添加它们的分词。另外,假设语言列用标准的 ISO 639-2 语言编码。
ctx_ddl.add_sub_lexer('global_lexer','german','german_lexer','ger');
ctx_ddl.add_sub_lexer('global_lexer','japanese','japanese_lexer','jpn');
现在,创建名为 "globalx" 的索引,在参数中指定多分词偏好和语言列,如下所示:
create index globalx on globaldoc(text) indextype is ctxsys.context
parameters ('lexer global_lexer language column lang');
BASIC_WORDLIST 示例: 启用子字符串和前缀索引
本例设置前缀和子字符串的词表偏好,以提高通配符查询的性能。
若建立前最索引,本例指定,Oracle 文本创建3到4个字符长度的前缀标记。如下所示:
begin
ctx_ddl.create_preference('mywordlist', 'BASIC_WORDLIST');
ctx_ddl.set_attribute('mywordlist','PREFIX_INDEX','TRUE');
ctx_ddl.set_attribute('mywordlist','PREFIX_MIN_LENGTH', '3');
ctx_ddl.set_attribute('mywordlist','PREFIX_MAX_LENGTH', '4');
ctx_ddl.set_attribute('mywordlist','SUBSTRING_INDEX', 'YES');
end;
创建 Section Groups 检索节
当文档具有内部结构时,如 HTML 和 XML,你可以在索引前使用内嵌标签来定义文档节。这样,就可以通过 WITHIN 运算符查询节。你可以定义节作为节组的一部分。
下面代码定义一个名为 "htmgroup " 、类型为 HTML_SECTION_GROUP 的节组。在 htmgroup 内创建一个用 <H1> 标记来识别 heading 的区域节:
begin
ctx_ddl.create_section_group('htmgroup', 'HTML_SECTION_GROUP');
ctx_ddl.add_zone_section('htmgroup', 'heading', 'H1');
end;
使用非索引字和非索引字列表
一个非索引字是一个不用被索引的字。通常,非索引字是信息量很地的字,如英语的 this 或 that。
系统为每个语言提供一个非索引字的列表,称为非索引子列表。默认情况下,系统使用你安装数据库时指定的语言的非索引字列表。
你可以编辑默认的非索引字列表 CTXSYS.DEFAULT_STOPLIST,或是用下面存储过程创建你自己的非索引字列表:
- CTX_DDL.CREATE_STOPLIST
- CTX_DDL.ADD_STOPWORD
- CTX_DDL.REMOVE_STOPWORD
你可以在 CREATE INDEX 子句的参数中指定自定义的非索引字列表。
你也可以在用 ALTER INDEX 改变索引后动态地添加非索引字列表。
多语言非索引子列表
你可以创建多语言非索引字列表。当你使用 MULTI_LEXER 来索引一个包含不同语言文档的表时,将非常有用。
若创建多语言非索引字列表,使用 CTX_DLL.CREATE_STOPLIST 存储过程,指定一个 MULTI_STOPLIST 类型。用 CTX_DDL.ADD_STOPWORD 添加语言特定的非索引字。
非索引主题和非索引类
除了定义你自己的非索引字外,你可以定制非索引主题。该功能只对英语和法语可用。
你可以可以指定不用被索引的数字。例如,数字,一类不用索引的字母数字字符是非索引类。
通过创建一个单独的非索引字列表,记录你自己的非索引字、非索引主题、非索引类,并且可以添加它们。在 CREATE INDEX 子句的参数中指定你的非索引字列表。
PL/SQL 存储过程管理非索引字列表
可以使用下面存储过程管理非索引字列表,非索引字,非索引主题和非索引类:
- CTX_DDL.CREATE_STOPLIST
- CTX_DDL.ADD_STOPWORD
- CTX_DDL.ADD_STOPTHEME
- CTX_DDL.ADD_STOPCLASS
- CTX_DDL.REMOVE_STOPWORD
- CTX_DDL.REMOVE_STOPTHEME
- CTX_DDL.REMOVE_STOPCLASS
- CTX_DDL.DROP_STOPLIST