yangtingkun
===========================================================
ORACLE TEXT LEXER PREFERENCE(二)
===========================================================

介绍完Oracle全文索引的BASIC_LEXER属性,这篇介绍Oracle中文语法属性CHINESE_LEXER和CHINESE_VGRAM_LEXER。


Oracle全文索引的BASIC属性主要是针对西方英语语系,英语语系的单词是通过空格、标点和回车来分隔的。而中文则需要索引来自动切词。

看下面这个例子:

SQL> CREATE TABLE T (ID NUMBER, DOCS VARCHAR2(1000));

表已创建。

SQL> INSERT INTO T VALUES (1, '一个中文例子,测试BASIC_LEXER语法属性是否可以正常识别中文。');

已创建 1 行。

SQL> COMMIT;

提交完成。

SQL> CREATE INDEX IND_T_DOCS ON T (DOCS) INDEXTYPE IS CTXSYS.CONTEXT;

索引已创建。

SQL> SELECT * FROM T WHERE CONTAINS(DOCS, '中文') > 0;

未选定行

SQL> SELECT * FROM T WHERE CONTAINS(DOCS, '一个中文例子') > 0;

ID DOCS
---------- ------------------------------------------------------------
1 一个中文例子,测试BASIC_LEXER语法属性是否可以正常识别中文。

通过BASIC_LEXER来索引中文,Oracle只识别被空格、标点和回车符分隔出来的部分。需要对中文内容进行索引的话,就必须使用中文的LEXER。

Oracle提供了两种预定义的中文LEXER属性:CHINESE_VGRAM_LEXER和CHINESE_LEXER。Oracle在文档上是这样描述的:

CHINESE_LEXER相对应CHINESE_VGRAM_LEXER属性有如下的优点:

产生的索引更小;

更好的查询响应时间;

产生更接近真实的索引切词,使得查询精度更高;

支持停用词。

虽然Oracle说明了使用CHINESE_LEXER的大量好处,但是CHINESE_LEXER的实际效果却存在一定的问题:

SQL> DROP INDEX IND_T_DOCS;

索引已丢弃。

SQL> TRUNCATE TABLE T;

表已截掉。

SQL> INSERT INTO T VALUES (1, '北京大学未名湖');

已创建 1 行。

SQL> INSERT INTO T VALUES (2, '北京邮电大学');

已创建 1 行。

SQL> INSERT INTO T VALUES (3, '北京市第十四中学');

已创建 1 行。

SQL> COMMIT;

提交完成。

SQL> CONN CTXSYS/CTXSYS@YANGTK
已连接。
SQL> BEGIN
2 CTX_DDL.CREATE_PREFERENCE('TEST_CHINESE_VGRAM_LEXER', 'CHINESE_VGRAM_LEXER');
3 CTX_DDL.CREATE_PREFERENCE('TEST_CHINESE_LEXER', 'CHINESE_LEXER');
4 END;
5 /

PL/SQL 过程已成功完成。

SQL> CONN YANGTK/YANGTK@YANGTK
已连接。
SQL> CREATE INDEX IND_T_DOCS ON T(DOCS) INDEXTYPE IS CTXSYS.CONTEXT
2 PARAMETERS ('LEXER CTXSYS.TEST_CHINESE_VGRAM_LEXER');

索引已创建。

SQL> SELECT * FROM T WHERE CONTAINS(DOCS, '北京') > 0;

ID DOCS
---------- ------------------------------------------------------------
3 北京市第十四中学
2 北京邮电大学
1 北京大学未名湖

SQL> DROP INDEX IND_T_DOCS;

索引已丢弃。

SQL> CREATE INDEX IND_T_DOCS ON T(DOCS) INDEXTYPE IS CTXSYS.CONTEXT
2 PARAMETERS ('LEXER CTXSYS.TEST_CHINESE_LEXER');

索引已创建。

SQL> SELECT * FROM T WHERE CONTAINS(DOCS, '北京') > 0;

ID DOCS
---------- ------------------------------------------------------------
2 北京邮电大学

通过对比结果可以发现:使用CHINESE_LEXER没有将第一条记录和第三条记录中的北京检索出来。也许Oracle的CHINESE_LEXER认为北京大学和北京市是一个完整的词汇,而没有对其进行进一步切分。也许这就是Oracle提到的这种切分方式更接近于真实的情况。我不知道读者会怎样看待这个问题,不过我更倾向于使用CHINESE_VGRAM_LEXER,个人感觉返回记录多一些总比漏掉一些要好。

yangtingkun 发表于:2006.08.06 17:03 ::分类: ( ORACLE ) ::阅读:(1573次) :: 评论 (2)
re: ORACLE TEXT LEXER PREFERENCE(二) [回复]

问一下,如果用CHINESE_VGRAM_LEXER时,如果查询的语句里混合了中文和数字,就会出现ora-03113,如下面几个例子:
select * from yw_jb_fwxx where CATSEARCH(fwzl,'环山',NULL)>0 --全中文,没有问题
select * from yw_jb_fwxx where CATSEARCH(fwzl,'环山路11a',NULL)>0 --数字和英语混在后面,没有问题
select * from yw_jb_fwxx where CATSEARCH(fwzl,'1',NULL)>0 -- 单数字,没有问题
select * from yw_jb_fwxx where CATSEARCH(fwzl,'环山路 1 号',NULL)>0 --数字在中文中间,出现ora-03113
select * from yw_jb_fwxx where CATSEARCH(fwzl,'椒江区环山路1号',NULL)>0--数字在中文中间,出现ora-03113

肯请指教!

lyrender 评论于: 2007.01.09 23:34
re: ORACLE TEXT LEXER PREFERENCE(二) [回复]

去论坛发给帖子说吧,这里不方便。

yangtingkun 评论于: 2007.01.10 09:45

发表评论
标题

在此添加评论
表情符号: smile laughing tongue angry crying sad wassat wink

称呼

邮箱地址(可选)

个人主页(可选)

 authimage


切换风格
新闻聚合
博客日历
文章归档...
最新发表...
最新评论...
最多阅读文章...
最多评论文章...
博客统计...
Blog信息
网站链接...