`
yupengcc
  • 浏览: 138824 次
  • 性别: Icon_minigender_1
  • 来自: 重庆
社区版块
存档分类
最新评论

oracle 全文检索实践

 
阅读更多

 

前段时间,项目中需要有一个实时检索数据的方案,并说明不是用数据库模糊查询关键字like,而是像baidu那样的搜索效果,做到最大匹配。并提示我看一下lucene。

我自己去的熟悉了下lucene,然后写了个demo,但他们说为了一个简单的查询检索,确引入了一个lucene,有点不划算。所以让我找其他的解决办法。

我找呀找,居然找到了select * from T where contains(F,'test',1)>0,这种oracle全文检索的方式,以前没见过的,貌似能解决我的问题。所以我就学习了一下oracle的全文检索。

在这里我记录了一下我的学习笔记,如果各位想要了解更全面的全文检索要点,请看这篇博客,讲的很详细,我认为非常非常的好。

http://yangtingkun.itpub.net/post/468/246823

 

1.oracle text

首先这里说oracle 全文检索,是针对我机器上的oracle 10g版本的。至少 10g 或以上的版本 适合这样来使用。

 

oracle 的全文检索,操作步骤为:将表中需要检索的字段,创建为全文检索的索引,然后通过select * from T where contains(F,'test',1)>0的语句进行全文检索,达到预期效果。

然后,oracle全文检索还是很强大的,能够检索文本啊、还有其他多种格式的文档。我做的测试只是针对数据库中的某一个字段的检索。比如针对地址表中的地址进行检索。

 

2.准备操作

首先,先建一个表用于测试,在名为testuser用户下建表。

 

 

create table YU_TEST(
    id number,
    name varchar2(50)
);

 

插入测试数据

 

 

insert into YU_TEST values(1,'重庆市沙坪坝区');
insert into YU_TEST values(2,'成都市青羊区');
insert into YU_TEST values(3,'北京市西城区');
insert into YU_TEST values(4,'重庆市两江新区');
insert into YU_TEST values(5,'上海市浦东新区金桥镇');
insert into YU_TEST values(6,'上海东方明珠');
insert into YU_TEST values(7,'江苏省无锡市国家软件园');
insert into YU_TEST values(8,'成都市天府软件园');
 

 

 

oracle全文检索需要ctxsys用户的支持,其实主要是需要使用ctxsys用户下的ctx_ddl这个包,这个包中绝大部分过程的创建都与全文检索有关。

 

首先需要对ctxsys用户解锁,以获得ctx_ddl包的操作权。

进入system用户,输入如下命令,解锁ctxsys用户

 

 

alter user ctxsys account unlock;

 

然后将ctx_ddl包的操作权限赋给testuser用户。

也是在system用户下,输入如下命令,赋予目标用户ctx_ddl包操作权限

 

 

grant execute on ctx_ddl to testuser;

 

至此,准备工作已经完成了

 

3.创建分析器

oracle text的分析器,类似于lucene中的分词器,将需要检索的记录,按照一定的方式进行词组拆分,然后存放在索引表中。检索的时候根据索引表中存放的拆分词组,对传入的关键字进行匹配,并返回匹配结果。

oracle text中的分析器有3种:

 

  • basic_lexer:只能根据空格和标点来进行拆分。比如“中国重庆”,只能拆分为“中国重庆”一个词组
  • chinese_vgram_lexer:专门的汉语分析器,按字单元进行拆分,比如“中国重庆”,可以拆分为“中”、“中国“、”国重”、“重庆”、“庆”五个词组。这种方式的好处是能够将所有有可能的词组全部保存进索引表,使得数据不会遗漏。
  • chinese_lexer:一种新的汉语分析器,能够认识大部分常用的汉语词汇,并按常用词汇进行拆分存储。比如“中国重庆”,只会被拆分为“中国”、“重庆”两个词组。

 

这里我使用chinese_lexer这个分词器,用testuser用户登录,执行下面的命令,创建分析器。

 

 

exec ctx_ddl.create_preference ('my_lexer', 'chinese_lexer');

 

 

这句话的意思是,创建一个“chinese_lexer”分析器,名称为my_lexer。

 

4.创建过滤词组

在我们建索引的时候,通常需要对一些常用的词组进行过滤,比如对公司名称进行检索时,肯定不希望输入“有限公司”、“公司”等关键词时,也会有搜索结果。

用testuser用户登录,执行下面的命令,创建过滤词组

 

 

exec ctx_ddl.create_stoplist('my_stoplist');

 

 

创建过滤词组成功以后,需要自定义需要过滤的词组

 

 

 

ctx_ddl.add_stopword('my_stoplist','有限公司');
ctx_ddl.add_stopword('my_stoplist','股份有限公司');

 

意思就是,创建了一个名为“my_stoplist”的过滤词组,“有限公司”、“股份有限公司”这两个词组不会被创建为索引

 

5.创建索引

其实前面的工作,都是为创建索引做准备的。

我要对YU_TEST表中的name字段进行检索,首先必须对name字段创建索引。

这里需要注意的是,name字段不能为nvarchar2类型,并且这个表的主键也不能为nvarchar2型,否则无法创建索引。

 

 

create index YU_TEST_INDEX on YU_TEST(name) indextype is CTXSYS.CONTEXT parameters('lexer my_lexer stoplist my_stoplist');
 

这句话的意思就是,在YU_TEST_INDEX表中的name字段上创建索引,索引类系那个为context类型,该索引用到的分析器为前面定义的my_lexer,该索引用到的过滤词组为前面定义得my_stoplist。

 

索引创建成功后,你回发现,在当前用户的表中,多了四个表

 

 

其中YU_TEST表中name字段被拆分后的词组保存在DR$YU_TEST_INDEX$I表中

 


这样可以看见索引的详细信息。

 

6.使用索引

 

 

select * from YU_TEST where contains(name,'重庆')>0;
 
  可以用contains来使用oracle的全文检索。
这样查出来的数据是没有经过排序的,有时候我们的需求是按照关键字的匹配程度排序,使用下面的语句:

select score(1),y.* from YU_TEST y where contains(name,'重庆',1)>0 order by score(1) desc;
 
这里的score是oracle全文检索对关键字的匹配程度所计算的分数,contains里的最后一个参数“1”就是对这个分数的一个标识

7.索引优化
前面已经能够进行检索了,现在就是对索引进行优化
当我们需要修改YU_TEST表中的数据,比如添加、删除、更新等操作时,YU_TEST_INDEX索引是不会同步更新数据的,需要我们在程序中手动的更新,可以写一个oracle的触发器,当添加、删除、修改操作时,进行索引更新。也可以定时进行更新。
索引同步:

exec ctx_ddl.sync_index('yu_test_index')
 
索引优化:

exec ctx_ddl.optimize_index('yu_test_index','full')
 
8.用户输入关键词切词

在执行检索的时候会发现这样的问题



 
表中存在两条“重庆”相关的记录和一条“天府”相关的记录,但是我传入“重庆天府”关键字时,确检索不出记录,这显然不是我们想要的结果,因为我们需要的是最大程度的匹配,传入“重庆天府”时应该同时检索出“重庆”相关和“天府”相关的信息。
要实现这种效果,需要用到oracle 10g的新特性,可以将传入的关键词先进行切词,然后在进行检索。
首先需要先创建一个POLICY过程

exec CTX_DDL.CREATE_POLICY('MY_POLICY', LEXER => 'my_lexer');
 
这里创建了一个名称为my_policy的policy过程,分析器用到了前面创建的my_lexer分析器

写一个oracle函数,来处理关键词切词:
create or replace function p_split_chinese(p_input in varchar2)
    return varchar2 as 
       v_tab CTX_DOC.TOKEN_TAB;
       v_return VARCHAR2(323767);
    begin
       CTX_DOC.POLICY_TOKENS('my_policy',p_input,v_tab);
       for i in 1..v_tab.count loop
          v_return := v_return || ',' || v_tab[i].token;
       end loop;
       return LTRIM(v_return,',');
     end;
/
 
在plsql 中执行这个函数

这样就可以将关键词切词,在程序中直接将这个切词结果,进行检索。


 
  可以看到这里显示的只有“天府”相关的信息,那么“重庆”相关的呢?
先看一下DR$YU_TEST_INDEX$I表中的结构。


 


 
发现token_text字段中,只有重庆市、北京市这些词,而没有重庆、北京之类的
所以会发现,oracle全文检索的chinese lexer分析器,对"重庆市",只会认为这只有一个词组,而不会把“重庆市”分为“重庆”和“重庆市”。
所以,如果需要比较精确的检索到结果,还是chinese_vgram_lexer分析器最好用,能够匹配到所有的词组。





  • 大小: 10.3 KB
  • 大小: 81.2 KB
  • 大小: 35.4 KB
  • 大小: 13.9 KB
  • 大小: 12.9 KB
  • 大小: 21.3 KB
  • 大小: 10.5 KB
分享到:
评论
1 楼 shenghuorulan 2012-08-20  
通俗易懂。好文章,直接想到的问题都提到了。

相关推荐

    ORACLE 全文检索实例.rar

    Oracle全文检索是数据库管理系统Oracle中的一个强大功能,它允许用户以自然语言的形式搜索数据库中的文本信息,而不仅仅是...这份精心整理的教程将引导你逐步完成整个过程,确保你在实践中能够顺利实施Oracle全文检索。

    Oracle全文检索

    Oracle全文检索是数据库管理系统Oracle中的一个重要特性,...通过阅读《Oracle全文检索.doc》文档,你将进一步了解Oracle Text的详细配置、使用示例和最佳实践,从而更好地利用这一功能强大的工具来提升数据检索效率。

    搜索引擎全文检索技术 oracle

    Oracle全文检索技术是数据库管理系统Oracle中的一个重要特性,它允许用户在数据库中进行高效、精确的文本搜索。全文检索技术能够理解自然语言,并从中提取出关键信息,为用户提供类似搜索引擎的体验。以下是对Oracle...

    基于Oracle组件的数据采集与全文检索系统设计与优化.pdf

    【Oracle组件在数据采集与全文检索中的应用】 Oracle数据库作为一款强大的关系型数据库管理系统,广泛应用于各类企业级应用中。本文主要探讨了如何利用Oracle组件,特别是Oracle Transparent Gateway和Oracle Text...

    oracle实践精华知识集

    《Oracle实践精华知识集》包含了过去三个月对Oracle数据库系统深入学习的丰富内容,涵盖了理论、实践、技巧和参考资料。此集合旨在为初学者提供全面的学习路径,帮助他们掌握Oracle的核心概念和技术。 首先,...

    ORACLE9i入门与实践

    《ORACLE9i入门与实践》是一本专为初学者设计的Oracle数据库教程,它旨在帮助读者快速掌握Oracle 9i的基本操作和管理技巧。Oracle是全球广泛使用的数据库管理系统之一,尤其在企业级应用中占据主导地位。Oracle 9i是...

    云栖专家带你技术进阶之全文检索和相似搜索实践.pdf

    ### 云栖专家带你技术进阶之全文检索和相似搜索实践 #### 阿里云RDSPostgreSQL实践课概览 ##### 搜索需求分析 在对数据进行搜索时,我们常常需要对信息进行分类处理,以满足不同的搜索需求。需求大致可以分为以下...

    Oracle数据库应用开发及实践.rar

    本资源包"Oracle数据库应用开发及实践.rar"是针对Oracle数据库应用开发的配套教学资源,旨在帮助学习者掌握Oracle的核心概念和技术,实现从理论到实践的转化。 首先,我们从"第1章 数据库概述.ppt"开始,这一章将...

    oracle性能优化最佳实践

    Oracle数据库性能优化最佳实践 在IT领域,Oracle数据库作为企业级数据管理的首选方案,其性能优化至关重要。本文旨在深入探讨Oracle数据库性能优化的最佳实践,包括数据库性能基础、调优方法论、SQL语句调优以及...

    从实践中学习Oracle SQL

    本教程“从实践中学习Oracle SQL”旨在帮助读者深入理解Oracle SQL的各个方面,通过实践案例来增强理解和应用能力。在完成学习后,你将能够熟练地进行数据查询、更新、插入和删除,以及进行更复杂的数据库操作。 ...

    oracle form 最佳实践

    ### Oracle Form 最佳实践知识点详解 #### 一、开发背景与基础 **1.1 读者基础要求** - **数据库基础知识:** 掌握Oracle数据库的基本操作,包括SQL语句的编写。 - **编程基础:** 了解PL/SQL语言的基础语法。 - ...

    基于Oracle地名地址检索技术研究.pdf

    总体来说,该文档详细探讨了基于Oracle数据库的地名地址检索技术,强调了数据量大、类型结构复杂、空间关系性强、系统变化快的地名地址检索服务特点,以及相关技术的应用与实践。这份研究对建设地名地址服务系统提供...

    从实践中学习Oracle SQL(非常适合新手学习Oracle数据库的书籍,全是实例)

    这本书《从实践中学习Oracle SQL》显然是一本旨在帮助新手快速掌握Oracle SQL语法和实践操作的教材。书中很可能涵盖了以下关键知识点: 1. **Oracle数据库基础知识**:这部分可能会介绍Oracle数据库的基本概念,如...

    Oracle 10g 数据库入门与实践

    本教程《Oracle 10g 数据库入门与实践》旨在帮助初学者掌握Oracle数据库的基本概念、操作和管理技巧,同时也为有经验的数据库管理员提供实践指导。 1. **SQL语句**(SQLstatements.doc) SQL(结构化查询语言)是...

    Red Hat Enterprise Linux 7部署Oracle+12c+RAC+最佳实践

    Red Hat Enterprise Linux 7部署Oracle 12c RAC最佳实践 Red Hat Enterprise Linux 7是一个功能强大且稳定的操作系统,对于企业级数据库的部署具有重要意义。Oracle 12c RAC(Real Application Clusters)是Oracle...

    从实践中学习Oracle/SQL

    本篇文章将深入探讨Oracle数据库的核心概念、SQL语言的基础知识以及在实践中的应用。 首先,Oracle数据库系统的核心组成部分包括数据文件、控制文件、重做日志文件和参数文件等。数据文件存储实际的数据库数据,...

    oracle实训报告

    这篇实训报告主要涵盖了Oracle数据库的基础操作、数据库连接以及基于Oracle构建学生成绩管理系统的实践过程,旨在让学生掌握Oracle的基本原理和操作技能。 首先,实践名称为“Oracle数据库开发”,其目的是在学生...

    oracle入门教材合集

    通过学习"从实践中学习Oracle SQL",你将学会如何创建、查询、更新和删除数据库中的表,使用SELECT语句进行复杂的数据检索,以及如何使用JOIN、索引、视图等提高数据操作效率。此外,还会接触到PL/SQL,这是Oracle的...

    从实践中学习Oracle SQL(下)

    ### Oracle SQL 实践学习(下) #### 一、Oracle SQL 基础回顾与实践 在上一篇文章中,我们详细介绍了 Oracle SQL 的基础知识,包括数据类型、表的创建与管理、基本查询语句等。本篇文章将继续深入探讨更高级的...

Global site tag (gtag.js) - Google Analytics