Oracle全文检索

Posted Oracle疑点通

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Oracle全文检索相关的知识,希望对你有一定的参考价值。

Oracle全文检索



一.授予dbuser执行ctx_ddl包的权限

由于Oracle全文检索需要用到ctx_ddl这个包,所以需要将ctx_ddl权限分配给dbuser

SQL> grant ctxapp to dbuser;

Grant succeeded.

用户ctxsys登录

SQL> connect ctxsys/root123;

ERROR:

ORA-28000: the account is locked

Warning: You are no longer connected to ORACLE.

用户被锁,解锁

SQL> conn sys/root123 as sysdba;

Connected.

SQL> alter user ctxsys account unlock;

User altered.

SQL> connect ctxsys/root123;

Connected.

SQL> grant execute on ctx_ddl to dbuser;--授予ctx_ddl权限

Grant succeeded.


二.设置词法分析器(lexer)

通过Oracle专利的词法分析器(lexer),将文章中所有的表意单元(Oracle 称为 term)找出来,记录在一组以dr$开头的表中,同时记下该term出现的位置、次数、hash值等信息。检索时,Oracle从这组表中查找相应的term,并计算其出现频率,根据某个算法来计算每个文档的得分(score),即所谓的‘匹配率’。而lexer则是该机制的核心,它决定了全文检索的效率。Oracle针对不同的语言提供了不同的lexer,而我们通常能用到其中的三个:

basic_lexer:针对英语。它能根据空格和标点来将英语单词从句子中分离,还能自动将一些出现频率过高已经失去检索意义的单词作为‘垃圾’处理,如if,is等,具有较高的处理效率。但该lexer应用于汉语则有很多问题,由于它只认空格和标点,而汉语的一句话中通常不会有空格,因此,它会把整句话作为一个term,事实上失去检索能力。以‘中国人民站起来了’这句话为例,basic_lexer分析的结果只有一个term,就是‘中国人民站起来了’。此时若检索‘中国’,将检索不到内容。

chinese_vgram_lexer:专门的汉语分析器,支持所有汉字字符集(ZHS16CGB231280 ZHS16GBK ZHT32EUC ZHT16BIG5 ZHT32TRIS ZHT16MSWIN950 ZHT16HKSCS UTF8 )。该分析器按字为单元来分析汉语句子。‘中国人民站起来了’这句话,会被它分析成如下几个term:‘中’,‘中国’,‘国人’,‘人民’,‘民站’,‘站起’,起来’,‘来了’,‘了’。可以看出,这种分析方法,实现算法很简单,并且能实现‘一网打尽’,但效率则是差强人意。

chinese_lexer:这是一个新的汉语分析器,只支持utf8字符集。上面已经看到,chinese vgram lexer这个分析器由于不认识常用的汉语词汇,因此分析的单元非常机械,像上面的‘民站’,‘站起’在汉语中根本不会单独出现,因此这种term是没有意义的,反而影响效率。chinese_lexer的最大改进就是该分析器能认识大部分常用汉语词汇,因此能更有效率地分析句子,像以上两个愚蠢的单元将不会再出现,极大提高了效率。但是它只支持utf8,如果你的数据库是zhs16gbk字符集,则只能使用笨笨的那个Chinese vgram lexer。如果不做任何设置,Oracle缺省使用basic_lexer这个分析器。 

BEGIN

ctx_ddl.create_preference ('my_lexer', 'chinese_vgram_lexer');  --配置词法分析器,这里使用chinese_vgram_lexer作为lexer


三.建立索引

--对file_content(blob类型)列建立文档CONTEXT索引,并且指定词法分析器

create index index_file_content on file_content (file_content)

indextype is ctxsys.context parameters ('lexer my_lexer');

--这样建立的全文检索索引,就会使用chinese_vgram_lexer作为词法分析器


四.使用索引

Select * from t_file where contains(file_content,’枪支弹药’) > 0;

--oracle通过contains进行检索,file_content字段如果存有一个word文档,那么通过该语句可--以检索出file_content列中出现‘枪支弹药’的所有文件


五.索引同步

当我们需要修改t_file表中的数据,比如添加、删除、更新等操作时,index_file_content索引是不会同步更新数据的,需要我们在程序中手动的更新,可以写一个oracle的job,定时进行更新。可使用sync同步索引,如下所示:

create or replace procedure cont_sync_index as

begin

ctx_ddl.sync_index('index_file_content');

end;

/

BEGIN

   DBMS_JOB.SUBMIT(:jobno,'cont_sync_index();', 

   SYSDATE, 'SYSDATE + (1/24/4)'); 

   commit; 

   END; 

   /

 

六.索引优化

       经常的索引同步将会导致索引产生碎片。索引碎片严重的影响了查询的反应速度。你可以定期优化索引来减少碎片,减少索引大小,提高查询效率。你必须以FULL模式优化索引,从索引中删除无效的旧的信息。这个过程叫做垃圾处理。当你经常的对表文本数据进行更新,删除操作的时候,垃圾处理是很必要的。

create or replace procedure cont_optimize_index as

  begin

  ctx_ddl.optimize_index('index_file_content','FULL');

  end;

  /

 

BEGIN

  DBMS_JOB.SUBMIT(:jobno,'cont_optimize_index();', 

  SYSDATE, 'SYSDATE + 1'); 

  commit;

  END;

  /

定期做索引同步及优化,可以提高全文检索的准确率和效率


七.总结

全文索引主要步骤分为:角色授权、创建词法分析器、创建索引、使用索引及索引优化等,它的作用包括:1.提高查询速度(在海量数据的情况下查询速度会提高n倍),2.切词,3.针对所有数据类型(包括blob等)进行全文检索,4.可以对超过150种文件类型(如doc,txt,pdf,xml)进行检索。



以上是关于Oracle全文检索的主要内容,如果未能解决你的问题,请参考以下文章

Oracle全文检索

oracle 数据库 索引 全文索引

Oracle全文检索是啥意思?

oracle全文检索笔记

oracle全文索引的创建和使用

如何更好的使用Oracle全文索引