ORACLE全文搜索中文

来源:互联网 发布:final java 变量 编辑:程序博客网 时间:2024/04/30 00:29

Oracle从7.3开始支持全文检索,即用户可以使用Oracle服务器的上下文(ConText)选项完 成基于文本的查询。具体可以采用通配符查找、模糊匹配、相关分类、近似查找、条件加权和词意扩充等方法。在Oracle8.0.x中 称为ConText ;在Oracle8i中 称为interMedia Text ; Oracle9i以后称为Oracle Text。下面通过示例了解一下oracle全文检索。

分派用户相应权限

grant connect,resource to scott; 
grant ctxapp to scott; 
alter user portal default role all; 
--对象权限
grant execute on ctx_ddl to scott; 

解锁ctxsys用户
alter user ctxsys account unlock identified by ctxsys; 

用应用用户登录,设置搜索器类型
SQL> conn scott/tiger;

BEGIN 
    ctx_ddl.create_preference ('main_lexer','CHINESE_LEXER'); 
    ctx_ddl.create_preference('mywordlist', 'BASIC_WORDLIST'); 
    ctx_ddl.set_attribute('mywordlist','PREFIX_INDEX','TRUE'); 
    ctx_ddl.set_attribute('mywordlist','PREFIX_MIN_LENGTH',1); 
    ctx_ddl.set_attribute('mywordlist','PREFIX_MAX_LENGTH', 5); 
    ctx_ddl.set_attribute('mywordlist','SUBSTRING_INDEX', 'YES'); 
END; 

这里说一下词法分析器(lexer) ,词法分析器有三种:
1)basic_lexer: 针对英语。它能根据空格和标点来 将英语单词从句子中分离,还能自动将一些出现频率过高已经失去检索意义的单词作为‘垃圾’处理,如if , is 等,具有较高的处理效率。但只认空格和标点,而汉语的一句话中通常不会有空格,会把整句话作为一个组,事实上失去检索能力。
2)chinese_vgram_lexer: 专门的汉语分析器,支持所有汉字 字符集(ZHS16CGB231280 ZHS16GBK ZHT32EUC ZHT16BIG5 ZHT32TRIS ZHT16MSWIN950 ZHT16HKSCS UTF8 )。但分词方法太简单,每个组合都作为一个词,既占用空间又效率不高。
3)chinese_lexer: 这是一个新的汉语分析器,只支持utf8字符集。chinese_lexer的最大改进就是能认识大部分常用汉语词汇,因此能更有效率地分析句子。

创建示例数据
create table docs( id number, name varchar2(200), address varchar2(2000) ); 
insert into docs values(1,'John Smith','Room 403,No.37,ShiFan Residential Quarter,BaoShan District');
insert into docs values(2,'Noah Abelard','Room 201,No.34,Lane 125,XiKang Road(South),HongKou District');
insert into docs values(3,'Michael Cole','Room 42, Zhongzhou Road,Nanyang City, Henan Prov. ');
insert into docs values(4,'Thomas Matthew','Hongyuan Hotel, Jingzhou city, Hubei Prov. ');
insert into docs values(5,'Joseph','Special Steel Corp,No.272, Bayi Road,Nanyang City, Henan Prov. ');
insert into docs values(6,'Lauren','Room 702, 7th Building, Hengda Garden, East District, Zhongshan ');
insert into docs values(7,'Kevin Victoria','Room 601, No.34 Long Chang Li, Xiamen, Fujian ');
insert into docs values(8,'Michael','Cheng Nuo Ban, Gong Jiao Zong Gong Si, Xiamen, Fujian ');
insert into docs values(9,'Timothy Katherine','NO. 204,Entrance A, Building NO. 1, The 2nd Dormitory of the NO. 4 State-owned Textile Factory, 53 Kaiping Road, Qingdao, Shandong');
insert into docs values(10,'Zhou Wangcai','Room 601, No.34 Long Chang Li,Xiamen, Fujian, China 361012');
insert into docs values(11,'Sebastian Jared','Cheng Nuo Ban, Gong Jiao Zong Gong SiXiamen, Fujian, China 361004');
insert into docs values(12,'Jenna','NO. 204, A, Building NO. 1,The 2nd Dormitory of the NO. 4 State-owned Textile Factory,53 Kaiping Road, Qingdao,Shandong, China 266042 ');
insert into docs values(13,'Catherine','Room403,No.37,SiFanResidentialQuarter,BaoShanDistrict');
insert into docs values(14,'Sebastian Cole','1 Team CaiQi ChuanXiBei Mining Area JiangYou City SiChuan Province China');
insert into docs values(15,'Timothy Jared ','Room 201,No.34,Lane 125,XiKang Road(South),HongKou District');
insert into docs values(16,'张三','中国北京朝阳区北小营亚运花园1号楼8B');
insert into docs values(17,'李四','上海世纪大道1500号9楼');

insert into docs values(18,'王五','四川成都经济技术开发区世纪大道515号');

commit;

对文本列建立文档CONTEXT索引,并且指定搜索器/过滤器/单词列表/ 
CREATE INDEX  idx_docs_address ON docs(address)  
indextype is ctxsys.context parameters  
('DATASTORE CTXSYS.DIRECT_DATASTORE FILTER CTXSYS.INSO_FILTER  LEXER main_lexer WORDLIST mywordlist');  


执行查询
SQL> select * from docs where contains(address,'朝阳区')>0;

        ID NAME                             ADDRESS
---------- -------------------------------- --------------------------------------------------
        16 张三                             中国北京朝阳区北小营亚运花园1号楼8B

SQL> select * from docs where contains(address,'朝阳区|成都')>0;


        ID NAME                             ADDRESS
---------- -------------------------------- -----------------------------------------------
        16 张三                             中国北京朝阳区北小营亚运花园1号楼8B
        18 王五                             四川成都经济技术开发区世纪大道515号

索引同步
insert into docs values(19,'赵六','九龙旺角山东街409号荣华大厦');
commit;

SQL> select * from docs where contains(address,'旺角')>0;

未选定行


SQL> exec ctx_ddl.sync_index('idx_docs_address'); 

SQL> select * from docs where contains(address,'旺角')>0;

        ID NAME                             ADDRESS
---------- ------------------ --------------------------------
        19 赵六                             九龙旺角山东街409号荣华大厦

创建同步job
CREATE or replace procedure cont_sync_index as 
BEGIN 
    ctx_ddl.sync_index('idx_docs_address'); 
END; 


VARIABLE jobno number;   
BEGIN 
       DBMS_JOB.SUBMIT(:jobno,'cont_sync_index();',   
       SYSDATE, 'SYSDATE + (1/24/4)');   
       commit;   
END;   


经常的索引同步将会导致CONTEXT索引产生碎片,索引碎片严重的影响了查询的反应速度。你可以定期优化索引来减少碎片,减少索引大 小,提高查询效率。创建索引优化job:
CREATE or replace procedure cont_optimize_index as 
BEGIN 
    ctx_ddl.optimize_index('idx_aritcle_content','FULL'); 
END; 


VARIABLE jobno number;   
BEGIN 
    DBMS_JOB.SUBMIT(:jobno,'cont_optimize_index();',   
    SYSDATE, 'SYSDATE + 1');   
    commit;  
END; 



原创粉丝点击