ORACLE 全文索引功能实现学习笔记

一、前言

    在Oracle数据库中搜索文本.可以使用标准的INSTR函数和LIKE操作符实现。

    SELECT * FROM tablename WHERE INSTR (thetext, 'Oracle') > 0;

     SELECT * FROM tablename WHERE thetext LIKE '%Oracle%';

    有很多时候,使用INSTR LIKE是很理想的特别是搜索仅跨越很小的表的时候.然而通过这些文本定位的方法将导致全表扫描,对资源来说消耗比较昂贵,而且实现的搜索功能也非常有限,因此对海量的文本数据进行搜索时,建议使用oralce提供的全文检索功能。

二、简介

        全文索引的技术原理并不复杂,对段落性的文本内容进行逐词分解,并针对词出现频率,出现位置进行标记,按照词本身的编码顺序存储为索引文件。这样,在针对关键词进行检索的时候,就不会遍历所有的文本数据记录,而是根据索引文件进行有序查找,这里面一个显见的事实是,通过有序索引查找关键词,对于海量的数据记录而言,也只需要很少次数的指针跳转,(数量为X的索引记录,查询特定记录的指针跳转次数最多为Log2(x)。)即可完成搜索,而无须完整遍历整个数据表或文件集。 
     但是全文索引技术的实现却并不简单,针对中文的尤其如此,英文文本中,空格是天然的分词标记,而中文段落却无法通过这样简单的途径分词,因此基于常用语词典和一些语言识别规则的分词技术成为一种非常高的技术门槛,幸好,很多商业公司提供了非常成熟的商业产品,使我等可以坐享其成,快速搭建全文搜索的平台。 

ORACLE INTERMEDIA介绍 
     ORACLE IntermediaORACLE公司官方发布的用来管理多媒体数据的数据库管理模块,通过它可以进行有效的视频,音频,图片等文件的统一存储,调用和相关处理;同时其中也包括一个Oracle Intermdedia Text功能模块,能够对多种格式文档进行分词索引处理,也提供了使用自然语法或高级查询方法进行跨文本查询的途径,可以查询word, PDF,RTF等格式的文件和数据。 
     Oracle Intermedia 的索引效率和查询效率,据一些公开数据上看要远高于MicrosoftIndex Server,而且本身具有平台无关特性,另外作为数据库产品,可以很好的和数据库应用进行整合,这一点也是纯粹的文件索引系统所无法实现的。当然,作为通用的数据库产品,Oracle不可能针对全文索引做到最大限度的优化,因此对于高并发大容量的搜索引擎应用,Oracle的方案可能就无法满足,这一点也是必须提前声明的。 

三、步骤

 3.1  查看Oracle Intermedia是否正确安装。即检查数据库中是否有CTXSYS用户和CTXAPP脚色。

       sqlplus "/as sysdba"

     select USERNAME from dba_users where USERNAME ='CTXSYS'; 

       select ROLE from dba_roles where ROLE='CTXAPP';

     如果没有这个用户和角色,意味着你的数据库创建时未安装intermedia功能,必须修改数据库以安装这项功能。

3.2 为用户分配权限(假设用户名为oracle

   把CTXAPP角色赋于当前用户: GRANT CTXAPP TO oracle;

   把CTX_DDL的执行权限赋于当前用户: GRANT EXECUTE ON CTX_DDL TO oracle;

   查看用户权限:SELECT * FROM dba_role_privs WHERE GRANTEE='oracle';

3.3设置词法解析器

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

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

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

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

    exec ctx_ddl.create_preference('testlex','CHINESE_LEXER'); //创建一个"CHINESE_LEXER"分析器,名称为"testlex"

3.4建立索引字段 

    create index inx_test  on talbe_name(column_name) indextype is CTXSYS.CONTEXT parameters('lexer testlex');  

    以上语句的意思是在talbe_namecolumn_name字段上创建全文索引名为inx_test,索引类型为CTXSYS.CONTEXT,用到了上面创建的分析器"testlex"

3.5 同步与优化

        在索引建好后,我们可以在该用户下查到Oracle自动产生了以下几个表DR$inx_test$IDR$inx_test$KDR$inx_test$RDR$inx_test$N,其中以I表最        重要,可以查询一下该表,看看有什么内容:

SELECT token_text, token_count FROM dr$i_rsk1$I WHERE ROWNUM <= 20;

       可以看到,该表中保存的其实就是Oracle 分析你的文档后,生成的term记录在这里,包括term出现的位置、次数、hash值等。当文档的内容改 变后,可以想见这个I表的内容也应该相应改变,才能保证Oracle在做全文检索时正确检索到内容(因为所谓全文检索,其实核心就是查询这个表)。 这就用到sync(同步和 optimize(优化)了。

    同步(sync): 将新的term 保存到I表。对表的DML操作是不会更新全文索引的,索引我们必须手动去维护索引。

    优化(optimize): 清除I表的垃圾,主要是将已经被删除的termI表删除。经常的索引同步将会导致你的CONTEXT索引产生碎片。索引碎片严重的 影响了查询的反应速度。你可以定期优化索引来减少碎片,减少索引大小,提高查询效率。

    exec ctx_ddl.sync_index('inx_test'); //同步索引,将新的数据同步到索引

    exec ctx_ddl.optimize_index('inx_test', 'FULL'); //优化索引,清除已删除的数据

3.6使用索引

   oracle全文索引使用时,sql语句必须使用contains关键字,具体如下:

   select * from test where contains(name,'深圳') > 0;

   如果需要根据匹配程度来排序,如下:

   select score(1),t.* from test t where contains(name,'深圳',1)>0 order by score(1) desc;

 

===========================================

以上内容未经过实际测试运行,咱不知可否。。

 


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值