全文检索是一种将文件中所有文本与检索项匹配的文字资料检索方法。全文检索系统是按照全文检索理论建立起来的用于提供全文检索服务的软件系统。
成都创新互联2013年开创至今,是专业互联网技术服务公司,拥有项目网站设计、成都网站设计网站策划,项目实施与项目整合能力。我们以让每一个梦想脱颖而出为使命,1280元长阳做网站,已为上家服务,为长阳各地企业和个人服务,联系电话:13518219792
判断检索效果的两个指标:
查全率=被检出相关信息量/相关信息总量(%)
查准率=被检出相关信息量/被检出信息总量(%)
Oracle全文检索配置方法:
1.检查数据库是否具有全文检索功能(这是针对已经建成使用的数据库)
查看用户中是否存在ctxsys用户,查询角色里是否存在ctxapp角色。以上两个中的1个不满足(不存在),则说明没有装过全文检索功能。
使用contains函数的时候,若没有全文检索则会报错的。
2.若没有,则需要手动建立,先建立全文检索要使用的空间
sqlplus / as sysdba --进入控制台
create tablespace Idx_ctxsys datafile '/oradata/sg186fx/ctxsys01.dbf size 10240M autoextend on next 32M maxsize 20480M;--创建全文检索使用的表空间
3.创建全文检索使用的用户和角色及相应的包,则需要执行oracle自带的一个脚本:cd $ORACLE_HOME/ctx/admin/catctx.sql
还是在sqlplus中执行:
@?/ctx/admin/catctx.sql ctxsys Idx_ctxsys temp nolock
在执行这个脚本的时候,输入了几个参数,第一个参数ctxsys为ctxsys用户的密码
第二个参数Idx_ctxsys为ctxsys用户要使用的表空间
第三个参数temp为ctxsys用户使用的临时表空间
第四个参数nolock为ctxsys用户处于解锁状态。
4.创建完成后,要登录ctxsys用户
connect ctxsys/ctxsys
执行以下脚本:@?/ctx/admin/defaults/drdefus.sql(这是个很重要的脚本,后面创建索引会使用该脚本创建的信息)
5.创建全文索引语法分析器
先要明确使用全文索引的用户,我要使用全文索引的是sgpm用户
因此
grant execute on ctxsys.ctx_ddl to sgpm with grant option;
connect sgpm/sgpm
设置语法分析器:
exec ctx_ddl.drop_preference('chinalexer');
exec ctx_ddl.create_preference('chinalexer','chinese_lexer');
设置词法属性:exec ctx_ddl.drop_preference('idx_c_store');
begin
ctx_ddl.create_preference('idx_c_store','BASIC_STORAGE');
ctx_ddl.set_attribut('idx_c_store','I_TABLE_CLAUSE','tablespaces Idx_ctxsy');
ctx_ddl.set_attribute('idx_c_store','I_INDEX_CLAUSE','tablespace Idx_ctxsy compress 2');
end;
/
6.创建索引
create index sgpm.idx_c_cons_name on sgpm.c_cons(cons_name) indextype is ctxsys.context parameters('lexer chinalexer storage idx_c_store');
7.同步索引
variable jobno number;
begin
dbms_job.submit(:jobno,'pkg_sp_tools.p_cont_sys_index();',sysdate,'trunc(sysdate)+19/24+1'); --执行的是个性化方法。
end;
/
普通的就是用:
exec ctx_ddl.sync_index('idx_c_cons_name');
到此,全文检索创建成功,contains函数就可以正常使用了。
注意:创建的过程中会出现ORA-29879:cannot create multiple domain index on a column listusing same indextype ,这说明在其他用户下已经建立了该索引。
在Oracle i Rlease 中 Oracle的全文检索技术被称为:Oracle Text 功能十分强大 Oracle Text是Oracle i采用的新名称 在Oracle / i中它被称作Oracle interMedia Text 在Oracle 以前它的名称是Oracle ConText Cartridge Oracle Text组件可以在安装数据库的时候选择 缺省是安装的 如果没有安装 那么可以按照以下方式手动安装Oracle Text 创建存储表空间
$ sqlplus / as sysdba SQL*Plus: Release Production on Sun May : : Copyright (c) Oracle Corporation All rights reserved Connected to: Oracle i Enterprise Edition Release bit Production With the Partitioning OLAP and Oracle Data Mining options JServer Release Production SQL select name from v$datafile; NAME /h love/oracle/system dbf /h love/oracle/undotbs dbf /h love/oracle/users dbf rows selected SQL create tablespace oratext datafile /h love/oracle/oratext dbf size m extent management local uniform size k ; Tablespace created
创建相关对象
SQL spool text log SQL connect sys/oracleHURRAY as sysdba Connected SQL start ?/ctx/admin/dr csys password oratext temp creating user CTXSYS creating role CTXAPP SQL connect ctxsys/password Connected SQL start ?/ctx/admin/dr inst ?/ctx/lib/libctxx so ============== ConText Database Objects Installation ============== This script must be run as CTXSYS This script will exit below if run as any other user User is CTXSYS creating tables and Oracle object types creating table dr$parameter creating table dr$class creating table dr$object creating table dr$object_attribute creating table dr$object_attribute_lov creating table dr$preference creating table dr$preference_value creating table dr$index creating table dr$index_partition creating table dr$index_value creating table dr$policy_tab creating table dr$sqe creating table dr$ths creating table dr$ths_phrase creating table dr$ths_fphrase creating table dr$ths_bt creating table dr$section_group creating table dr$section creating table dr$stoplist creating table dr$stopword creating table dr$sub_lexer creating table dr$index_set creating table dr$index_set_index creating table dr$server creating table dr$pending creating table dr$waiting creating table dr$online_pending creating table dr$delete creating table dr$unindexed creating table dr$index_error creating table dr$parallel creating table dr$stats creating table dr$part_stats creating named data type ctx_feedback_item_type creating named data type ctx_feedback_type creating safe callout library creating CONTEXT interface drop public synonym contains * ERROR at line : ORA : public synonym to be dropped does not exist drop public synonym score * ERROR at line : ORA : public synonym to be dropped does not exist creating CTXCAT interface drop public synonym catsearch * ERROR at line : ORA : public synonym to be dropped does not exist creating CTXRULE interface drop public synonym matches * ERROR at line : ORA : public synonym to be dropped does not exist creating CTXXPATH interface loading package headers ================== Package Installation ========================== Install Global Symbols loading driobj pkh No errors loading dr def pkh No errors loading drig pkh No errors Install DR Internal package specs loading driutl pkh No errors loading driacc pkh No errors loading driadm pkh No errors loading dricon pkh No errors loading dridisp pkh No errors loading dridml pkh No errors loading dridoc pkh No errors loading drierr pkh No errors loading driddl pkh No errors loading driddlp pkh No errors loading driddlc pkh No errors loading driddlr pkh No errors loading driddlx pkh No errors loading drilist pkh No errors loading driload pkh No errors loading driopt pkh No errors loading dripipe pkh No errors loading dripref pkh No errors loading drirec pkh No errors loading drirep pkh No errors loading drirepm pkh No errors loading drireps pkh No errors loading drirept pkh No errors loading drirepz pkh No errors loading driths pkh No errors loading drithsc pkh No errors loading drithsd pkh No errors loading drithsl pkh No errors loading drithsx pkh No errors loading drival pkh No errors loading driexp pkh No errors loading driimp pkh No errors loading driparse pkh No errors loading drixtab pkh No errors loading drixtabc pkh No errors loading drixtabr pkh No errors loading drixtabx pkh No errors Install ConText public API specs loading dr adm pkh No errors loading dr ddl pkh No errors loading dr doc pkh No errors loading dr out pkh No errors loading dr query pkh No errors loading dr thes pkh No errors loading dr repor pkh No errors loading dr ulex pkh No errors loading dr cls pkh No errors loading package bodies ================== Package Installation ========================== Install DR Internal package bodies loading driacc plb No errors loading driadm plb No errors loading dricon plb No errors loading dridisp plb No errors loading dridml plb No errors loading dridoc plb No errors loading drierr plb No errors loading driddl plb No errors loading driddlp plb No errors loading driddlc plb No errors loading driddlr plb No errors loading driddlx plb No errors loading drilist plb No errors loading driload plb No errors loading dripipe plb No errors loading driopt plb No errors loading dripref plb No errors loading drirec plb No errors loading drirep plb No errors loading drirepm plb No errors loading drireps plb No errors loading drirept plb No errors loading drirepz plb No errors loading driths plb No errors loading drithsc plb No errors loading drithsd plb No errors loading drithsl plb No errors loading drithsx plb No errors loading driutl plb No errors loading drival plb No errors loading driexp plb No errors loading driimp plb No errors loading driparse plb No errors loading drixtab plb No errors loading drixtabc plb No errors loading drixtabr plb No errors loading drixtabx plb No errors loading driproc plb No errors Install ConText public API bodies loading dr adm plb No errors loading dr ddl plb No errors loading dr doc plb No errors loading dr out plb No errors loading dr query plb No errors loading dr thes plb No errors loading dr repor plb No errors loading dr cls plb No errors ======================================================== creating CONTEXT interface body No errors No errors creating CTXCAT interface body No errors creating CTXRULE interface body No errors creating CTXXPATH interface body No errors creating CONTEXT index type drop public synonym context * ERROR at line : ORA : public synonym to be dropped does not exist creating CTXCAT index type drop public synonym ctxcat * ERROR at line : ORA : public synonym to be dropped does not exist creating CTXRULE index type drop public synonym ctxrule * ERROR at line : ORA : public synonym to be dropped does not exist creating CTXXPATH index type drop public synonym ctxxpath * ERROR at line : ORA : public synonym to be dropped does not exist creating objects Removing old object definitions Creating new object definitions creating default preferences Create default preferences System Parameters ======================================================== SQL start ?/ctx/admin/defaults/drdefus sql; Creating lexer preference Creating wordlist preference Creating stoplist Creating default policy SQL spool off SQL exit Disconnected from Oracle i Enterprise Edition Release bit Production With the Partitioning OLAP and Oracle Data Mining options JServer Release Production
请注意如果漏掉drdefus sql脚本 使用过程中将会出现以下类似错误
ERROR atline : ORA : error occurred in the execution of ODCIINDEXCREATEroutine ORA : interMedia Text error: DRG : preference does notexist: CTXSYS DEFAULT_LEXER ORA : at CTXSYS DRUE line ORA :at CTXSYS TEXTINDEXMETHODS line ORA : at line
lishixinzhi/Article/program/Oracle/201311/17795
不使用Oracle text功能,也有很多方法可以在Oracle数据库中搜索文本.可以使用标准的INSTR函数和LIKE操作符实现。
SELECT *FROM mytext WHERE INSTR (thetext, 'Oracle') 0;
SELECT * FROM mytext WHERE thetext LIKE '%Oracle%';
有很多时候,使用instr和like是很理想的, 特别是搜索仅跨越很小的表的时候.然而通过这些文本定位的方法将导致全表扫描,对资源来说消耗比较昂贵,而且实现的搜索功能也非常有限,因此对海量的文本 数据进行搜索时,建议使用oralce提供的全文检索功能 建立全文检索的步骤步骤一 检查和设置数据库角色首先检查数据库中是否有CTXSYS用户和CTXAPP脚色。如果没有这个用户和角色,意味着你的数据库 创建时未安装intermedia功能。你必须修改数据库以安装这项功能。 默认安装情况下,ctxsys用户是被锁定的,因此要先启用ctxsys的用 户。 步骤二 赋权 在ctxsys用户下把ctx_ddl的执行权限赋于要使用全文索引的用户,例:
grant execute on ctx_ddl to pomoho;
步骤三 设置词法分析器(lexer)
Oracle实现全文检索,其机制其实很简单。即通过Oracle专利的词法分析器(lexer),将文章中所有的表意单元(Oracle 称为 term)找出来,记录在一组 以dr$开头的表中,同时记下该term出现的位置、次数、hash 值等信息。检索时,Oracle 从这组表中查找相应的term,并计算其出现频率,根据某个算法来计算每个文档的得分(score),即所谓的‘匹配率’。而lexer则是该机制的核 心,它决定了全文检索的效率。Oracle 针对不同的语言提供了不同的 lexer, 而我们通常能用到其中的三个:
n basic_lexer: 针对英语。它能根据空格和标点来将英语单词从句子中分离,还能自动将一些出现频率过高已经失去检索意义的单词作为‘垃圾’处理,如if , is 等,具有较高的处理效率。但该lexer应用于汉语则有很多问题,由于它只认空格和标点,而汉语的一句话中通常不会有空格,因此,它会把整句话作为一个 term,事实上失去检索能力。以‘中国人民站起来了’这句话为例,basic_lexer 分析的结果只有一个term ,就是‘中国人民站起来了’。此时若检索‘中国’,将检索不到内容。
n chinese_vgram_lexer: 专门的汉语分析器,支持所有汉字字符集(ZHS16CGB231280 ZHS16GBK ZHT32EUC ZHT16BIG5 ZHT32TRIS ZHT16MSWIN950 ZHT16HKSCS UTF8 )。该分析器按字为单元来分析汉语句子。‘中国人民站起来了’这句话,会被它分析成如下几个term: ‘中’,‘中国’,‘国人’,‘人民’,‘民站’,‘站起’,起来’,‘来了’,‘了’。可以看出,这种分析方法,实现算法很简单,并且能实现‘一网打 尽’,但效率则是差强人意。
n chinese_lexer: 这是一个新的汉语分析器,只支持utf8字符集。上面已经看到,chinese vgram lexer这个分析器由于不认识常用的汉语词汇,因此分析的单元非常机械,像上面的‘民站’,‘站起’在汉语中根本不会单独出现,因此这种term是没有 意义的,反而影响效率。chinese_lexer的最大改进就是该分析器 能认识大部分常用汉语词汇,因此能更有效率地分析句子,像以上两个愚蠢的单元将不会再出现,极大 提高了效率。但是它只支持 utf8, 如果你的数据库是zhs16gbk字符集,则只能使用笨笨的那个Chinese vgram lexer.
如果不做任何设置,Oracle 缺省使用basic_lexer这个分析器。要指定使用哪一个lexer, 可以这样操作:
第一. 当前用户下下建立一个preference(例:在pomoho用户下执行以下语句)
exec ctx_ddl.create_preference ('my_lexer', 'chinese_vgram_lexer');
第二. 在建立全文索引索引时,指明所用的lexer:
CREATE INDEX myindex ON mytable(mycolumn) indextype is ctxsys.context
parameters('lexer my_lexer');
这样建立的全文检索索引,就会使用chinese_vgram_lexer作为分析器。
步骤四 建立索引
通过以下语法建立全文索引
CREATE INDEX [schema.]index on [schema.]table(column) INDEXTYPE IS ctxsys.context [ONLINE]
LOCAL [(PARTITION [partition] [PARAMETERS('paramstring')]
[, PARTITION [partition] [PARAMETERS('paramstring')]])]
[PARAMETERS(paramstring)] [PARALLEL n] [UNUSABLE];
例:
CREATE INDEX ctx_idx_menuname ON pubmenu(menuname)
indextype is ctxsys.context parameters('lexer my_lexer')
步骤五 使用索引
使用全文索引很简单,可以通过:
select * from pubmenu where contains(menuname,'上传图片')0
全文索引的种类
建立的Oracle Text索引被称为域索引(domain index),包括4种索引类型:
l CONTEXT
2 CTXCAT
3 CTXRULE
4 CTXXPATH
依据你的应用程序和文本数据类型你可以任意选择一种。
对多字段建立全文索引
很多时候需要从多个文本字段中查询满足条件的记录,这时就需要建立针对多个字段的全文索引,例如需要从pmhsubjects(专题表)的 subjectname(专题名称)和briefintro(简介)上进行全文检索,则需要按以下步骤进行操作:
Ø 建议多字段索引的preference
以ctxsys登录,并执行:
EXEC ctx_ddl.create_preference(' ctx_idx_subject_pref',
'MULTI_COLUMN_DATASTORE');
Ø 建立preference对应的字段值(以ctxsys登录)
EXEC ctx_ddl.set_attribute(' ctx_idx_subject_pref ','columns','subjectname,briefintro');
Ø 建立全文索引
CREATE INDEX ctx_idx_subject ON pmhsubjects(subjectname)
INDEXTYPE ISctxsys.CONTEXT PARAMETERS('DATASTORE ctxsys.ctx_idx_subject_pref lexer my_lexer')
Ø 使用索引
select * from pmhsubjects where contains(subjectname,'李宇春')0
全文索引的维护
对于CTXSYS.CONTEXT索引,当应用程序对基表进行DML操作后,对基表的索引维护是必须的。索引维护包括索引同步和索引优化。
在索引建好后,我们可以在该用户下查到Oracle自动产生了以下几个表:(假设索引名为myindex):
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;
这里就不列出查询接过了。可以看到,该表中保存的其实就是Oracle 分析你的文档后,生成的term记录在这里,包括term出现的位置、次数、hash值等。当文档的内容改变后,可以想见这个I表的内容也应该相应改变, 才能保证Oracle在做全文检索时正确检索到内容(因为所谓全文检索,其实核心就是查询这个表)。这就用到sync(同步) 和 optimize(优化)了。
同步(sync): 将新的term 保存到I表;
优化(optimize): 清除I表的垃圾,主要是将已经被删除的term从I表删除。
当基表中的被索引文档发生insert、update、delete操作的时候,基表的改变并不能马上影响到索引上直到同步索引。可以查询视图 CTX_USER_PENDING查看相应的改动。例如:
SELECT pnd_index_name, pnd_rowid,
TO_CHAR (pnd_timestamp, 'dd-mon-yyyy hh24:mi:ss') timestamp
FROM ctx_user_pending;
该语句的输出类似如下:
PND_INDEX_NAME PND_ROWID TIMESTAMP
------------------------------ ------------------ --------------------
MYINDEX AAADXnAABAAAS3SAAC 06-oct-1999 15:56:50
同步和优化方法: 可以使用Oracle提供的ctx_ddl包同步和优化索引
一. 对于CTXCAT类型的索引来说, 当对基表进行DML操作的时候,Oracle自动维护索引。对文档的改变马上反映到索引中。CTXCAT是事务形的索引。
索引的同步
在对基表插入,修改,删除之后同步索引。推荐使用sync同步索引。语法:
ctx_ddl.sync_index(
idx_name IN VARCHAR2 DEFAULT NULL
memory IN VARCHAR2 DEFAULT NULL,
part_name IN VARCHAR2 DEFAULT NULL
parallel_degree IN NUMBER DEFAULT 1);
idx_name 索引名称
memory 指定同步索引需要的内存。默认是系统参数DEFAULT_INDEX_MEMORY 。
指定一个大的内存时候可以加快索引效率和查询速度,且索引有较少的碎片
part_name 同步哪个分区索引。
parallel_degree 并行同步索引。设置并行度。
例如:
同步索引myindex:Exec ctx_ddl.sync_index ('myindex');
实施建议:建议通过oracle的job对索引进行同步
索引的优化
经常的索引同步将会导致你的CONTEXT索引产生碎片。索引碎片严重的影响了查询的反应速度。你可以定期优化索引来减少碎片,减少索引大小,提高 查询效率。
当文本从表中删除的时候,Oracle Text标记删除的文档,但是并不马上修改索引。因此,就的文档信息占据了不必要的空间,导致了查询额外的开销。你必须以FULL模式优化索引,从索引中 删除无效的旧的信息。这个过程叫做垃圾处理。当你经常的对表文本数据进行更新,删除操作的时候,垃圾处理是很必要的。
exec ctx_ddl.optimize_index ('myidx', 'full');
实施建议:每天在系统空闲的时候对全 文索引进行相应的优化,以提高检索的效率
对多字段建立全文索引
很多时候需要从多个文本字段中查询满足条件的记录,这时就需要建立针对多个字段的全文索引,例如需要从pmhsubjects(专题表)的subjectname(专题名称)和briefintro(简介)上进行全文检索,则需要按以下步骤进行操作:
??
建议多字段索引的preference
以ctxsys登录,并执行:
全文索引的维护
对于CTXSYS.CONTEXT索引,当应用程序对基表进行DML操作后,对基表的索引维护是必须的。索引维护包括索引同步和索引优化。
在索引建好后,我们可以在该用户下查到Oracle自动产生了以下几个表:(假设索引名为myindex):
DR$myindex$I、DR$myindex$K、DR$myindex$R、DR$myindex$N其中以I表最重要,可以查询一下该表,看看有什么内容:
这里就不列出查询接过了。可以看到,该表中保存的其实就是Oracle
分析你的文档后,生成的term记录在这里,包括term出现的位置、次数、hash值等。当文档的内容改变后,可以想见这个I表的内容也应该相应改变,才能保证Oracle在做全文检索时正确检索到内容(因为所谓全文检索,其实核心就是查询这个表)。这就用到sync(同步)
和
optimize(优化)了。
同步(sync):
将新的term
保存到I表;
优化(optimize):
清除I表的垃圾,主要是将已经被删除的term从I表删除。
当基表中的被索引文档发生insert、update、delete操作的时候,基表的改变并不能马上影响到索引上直到同步索引。可以查询视图CTX_USER_PENDING查看相应的改动。例如:
同步和优化方法:
可以使用Oracle提供的ctx_ddl包同步和优化索引
一.
对于CTXCAT类型的索引来说,
当对基表进行DML操作的时候,Oracle自动维护索引。对文档的改变马上反映到索引中。CTXCAT是事务形的索引。
索引的同步
在对基表插入,修改,删除之后同步索引。推荐使用sync同步索引。语法:
指定一个大的内存时候可以加快索引效率和查询速度,且索引有较少的碎片
part_name
同步哪个分区索引。
parallel_degree
并行同步索引。设置并行度。
例如:
同步索引myindex:Exec
ctx_ddl.sync_index
('myindex');
实施建议:建议通过oracle的job对索引进行同步
索引的优化
经常的索引同步将会导致你的CONTEXT索引产生碎片。索引碎片严重的影响了查询的反应速度。你可以定期优化索引来减少碎片,减少索引大小,提高查询效率。
oracle可以支持多个字段上的全文索引,但如果还涉及到多张表的话,就只能在每张表上建一个全文索引。但这样的话,查询时很不方便。而且如果涉及到的表或者字段发生变化,需要重新建全文索引,可扩展性不佳。
另一个思路是专门建立一张中间表,其中包括以下字段:表名,字段名,字段值,对象ID。在字段值这个字段上建立全文索引。然后定时的将原来四张表中须检索的字段同步到此中间表(可考虑用物化视图)。查询时,直接对此中间表进行查询即可。
举个例子:假设原表是文章表,其中有如下一条数据:
ID
标题
内容
作者
1
德川家康为什么能统一日本?
请教一下,为什么最后是德川家康统一日本呢?
德川家康粉
现在需要检索在标题,内容或作者字段中存在“德川家康”的数据。
首先,需要将原数据同步到中间表,变成以下三条数据:
表名
字段名
字段值
对象ID
文章表
标题
德川家康为什么能统一日本?
1
文章表
内容
请教一下,为什么最后是德川家康统一日本呢?
1
文章表
作者
德川家康粉
1
通过在字段值这个字段上全文检索“德川家康”,可以筛选出以上三条数据。这三条数据都指向文章表中的ID=1的文章。从文章表里取出这条数据,检索就成功结束了。
此方法的优点:一是检索的速度比较快;二是可以兼容指定表或指定字段的检索;三是需要检索的表或字段可以动态删减,可扩展性好。
主要的缺点一是需要一张中间表,并定时同步,消耗额外的服务器资源,二是同步的过程会造成延时,即新修改但尚未同步的数据会暂时检索不到。