1.sysdba用户授权
grant ctxapp to xmaricallplat;
grant ctx_ddl execute on xmaircallplat;
2.选择分析器
basic_lexer:针对英语分词器
chinese_vgram_lexer:专门的汉语分析器(支持所有汉字字符集),搜索特点:一网打尽、效率差强人意
chinese_lexer:新的汉语分析器(只支持utf8字符集),搜索特点:能够搜索大部分常用汉语词汇,效率较高
3.创建全文索引
-- 创建分析器和创建单字段的全文索引
exec ctx_ddl.create_preference('my_lexer','chinese_vgram_lexer');
create index kb_index on kb_node_text(kb_text) indextype is ctxsys.context parameters('lexer my_lexer');
-- 创建多字段的全文索引
exec ctx_ddl.create_preference('ctx_idx_subject_pref','MULTI_COLUMN_DATASTORE');
exec ctx_ddl.set_attribute('ctx_idx_subject_pref','coloumns',,'subjectname,briefintro');
create index ctx_idx_subject_pref on pmhsubjects(subjectname)
indextype is ctxsys.context parameters('DATASTORE ctxsys.ctx_idx_subject_pref exer my_lexer');
--查看自定义的参考项
select * from ctx_user_preferences;
4.简单介绍索引类型
context -- 复杂索引类型(支持普通和大字段类型如clob、blob)
ctxcat -- 简单索引类型(支持普通类型,不支持大字段类型)
ctxrule
ctxpath
5.使用全文索引
select * from kb_node_text where contains(kb_text,'老大') > 0;
6.全文索引的维护
对应ctxsys.context索引,会产生DR$myindex$I、DR$myindex$K、DR$myindex$R、DR$myindex$N四个表,主要是I表:
SELECT token_text, token_count FROM dr$i_rsk1$I WHERE ROWNUM <= 20;(用来存分词记录,所谓全文索引,核心就是查询这个表),对应context类型需要进行sync(同步)和optimize(优化)
同步(sync): 将新的term 保存到I表
优化(optimize): 清除I表的垃圾,主要是将已经被删除的term从I表删除
查询基本的改变,可以查询视图CTX_USER_PENDING查看相应的改动:
select pnd_index_name, pnd_rowid,to_char (pnd_timestamp, 'dd-mon-yyyy hh24:mi:ss') timestamp from ctx_user_pending;
注意:对于CTXCAT类型的索引来说, 当对基表进行DML操作的时候,Oracle自动维护索引。对文档的改变马上反映到索引中。CTXCAT是事务形的索引
同步和优化方法: 可以使用Oracle提供的ctx_ddl包同步和优化索引
手动同步:exec ctx_ddl.sync_index('kb_index');
手动优化:exec ctx_ddl.optimize_index('kb_index','full');
为了保持索引记录和基本的同步的,可以采用定时优化同步域索引:
(1)创建同步存储过程
create or replace procedure sync_kb_index as
begin
ctxsys.ctx_ddl.sync_index('kb_index');
end;
(2)创建优化存储过程
create or replace procedure optimize_kb_index as
begin
ctx_ddl.optimize_index('kb_index','FULL');
end;
(3)创建同步定时任务
variable jobno number;
begin
dbms_job.submit(:jobno,'sync_kb_index();',
sysdate, 'sysdate + 1');
commit;
end;
(4)创建优化定时任务
variable jobno number;
begin
dbms_job.submit(:jobno,'optimize_kb_index();',
sysdate, 'sysdate + 2');
commit;
end;