关闭

ORACLE TEXT LEXER PREFERENCE(三)

标签: oraclesql语言parametersinsertbasic
764人阅读 评论(0) 收藏 举报
分类:

本文继续介绍Oracle全文索引的LEXER属性,这篇文章介绍Oracle多语言全文索引MULTI_LEXER。


如果在Oracle中存储多种语言,那么在建立全文索引的时候就不能只是简单的指定一个LEXER,而是要通过LANGUAGE COLUMN设置MULTI_LEXER。

下面看一个简单的例子:

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

表已创建。

SQL> INSERT INTO T VALUES (1, 'english', 'This is a mixed language example.');

已创建 1 行。

SQL> INSERT INTO T VALUES (2, 'chinese', '中文信息应该使用中文语言属性CHINESE_VGRAM_LEXER进行索引');

已创建 1 行。

SQL> INSERT INTO T VALUES (3, 'chinese', '英文记录虽然可以通过中文语言属性CHINESE_VGRAM_LEXER继续索引');

已创建 1 行。

SQL> INSERT INTO T VALUES (4, '', 'But all the words is indexed by UPPER FORMAT.');

已创建 1 行。

SQL> COMMIT;

提交完成。

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

索引已创建。

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

未选定行

如果使用BASIC_LEXER作为LEXER属性的选项,那么就无法对中文使用索引。

SQL> DROP INDEX IND_T_DOCS;

索引已丢弃。

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

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_LEXER');

索引已创建。

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

ID LANGUAG DOCS
---------- ------- ----------------------------------------------------------
3 chinese 英文记录虽然可以通过中文语言属性CHINESE_VGRAM_LEXER继续索引
2 chinese 中文信息应该使用中文语言属性CHINESE_VGRAM_LEXER进行索引

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

ID LANGUAG DOCS
---------- ------- ---------------------------------------------------------
4 But all the words is indexed by UPPER FORMAT.

如果使用CHINESE_VGRAM_LEXER属性的话,虽然可以对英文进行索引,但是中文LEXER无法进行属性的设置,如果想要对英文进行大小写敏感的查询,使用CHINESE_VGRAM_LEXER属性是不行的,必须使用BASIC_LEXER,并进行MIXED_CASE属性设置。

SQL> DROP INDEX IND_T_DOCS;

索引已丢弃。

SQL> CONN CTXSYS/CTXSYS@YANGTK
已连接。
SQL> BEGIN
2 CTX_DDL.CREATE_PREFERENCE('TEST_ENGLISH', 'BASIC_LEXER');
3 CTX_DDL.SET_ATTRIBUTE('TEST_ENGLISH', 'MIXED_CASE', 'YES');
4 CTX_DDL.CREATE_PREFERENCE('TEST_CHINESE', 'CHINESE_LEXER');
5 CTX_DDL.CREATE_PREFERENCE('TEST_MULTI_LEXER', 'MULTI_LEXER');
6 CTX_DDL.ADD_SUB_LEXER('TEST_MULTI_LEXER', 'DEFAULT', 'TEST_ENGLISH');
7 CTX_DDL.ADD_SUB_LEXER('TEST_MULTI_LEXER', 'SIMPLIFIED CHINESE', 'TEST_CHINESE', 'CHINESE');
8 END;
9 /

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_MULTI_LEXER LANGUAGE COLUMN LANGUAGE');

索引已创建。

建立一个MULTI_LEXER属性的索引,并通过LANGUAGE列设置需要索引的语言。Oracle会根据LANGUAGE列的内容去匹配ADD_SUB_LEXER过程中指定的语言标识符。如果匹配的上,就使用该SUB_LEXER作为索引的LEXER,如果没有找到匹配的,就使用DEFAULT语言作为索引的LEXER列。

上面虽然建立了MULTI_LEXER索引,但是对多语言索引的查询却还存在一些额外的问题:

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

ID LANGUAG DOCS
---------- ------- ----------------------------------------------------------
3 chinese 英文记录虽然可以通过中文语言属性CHINESE_VGRAM_LEXER继续索引
2 chinese 中文信息应该使用中文语言属性CHINESE_VGRAM_LEXER进行索引

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

未选定行

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

未选定行

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

ID LANGUAG DOCS
---------- ------- ------------------------------------------------
4 But all the words is indexed by UPPER FORMAT.

通过上面的查询结果可以推测出,BASIC_LEXER并没有起作用。对于中文的查询可以生效,但是对于字符大小写敏感的查询都不会生效。可以生效的查询只是原文中就使用大写的单词。

这是由于当前客户端的语言设置是简体中文,这和索引中的一个SUB_LEXER相匹配,因此Oracle选择了该LEXER的索引结果作为查询的返回结果。下面将NLS_LANGUAGE设置为英文:

SQL> SELECT * FROM V$NLS_PARAMETERS WHERE PARAMETER = 'NLS_LANGUAGE';

PARAMETER VALUE
------------------------------ ----------------------------------------
NLS_LANGUAGE SIMPLIFIED CHINESE

SQL> ALTER SESSION SET NLS_LANGUAGE = 'AMERICAN';

Session altered.

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

ID LANGUAG DOCS
---------- ------- -----------------------------------------------------------
3 chinese 英文记录虽然可以通过中文语言属性CHINESE_VGRAM_LEXER继续索引
2 chinese 中文信息应该使用中文语言属性CHINESE_VGRAM_LEXER进行索引

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

no rows selected

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

ID LANGUAG DOCS
---------- ------- --------------------------------------------------------
4 But all the words is indexed by UPPER FORMAT.

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

ID LANGUAG DOCS
---------- ------- --------------------------------------------------------
4 But all the words is indexed by UPPER FORMAT.

结果恢复了正常,如果将语言不设置为DEFAULT LEXER,而是设置索引包含的LEXER以外的语言,查询也是正常的。

SQL> ALTER SESSION SET NLS_LANGUAGE = 'TRADITIONAL CHINESE';

Session altered.

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

ID LANGUAG DOCS
---------- ------- -----------------------------------------------------------
3 chinese 英文记录虽然可以通过中文语言属性CHINESE_VGRAM_LEXER继续索引
2 chinese 中文信息应该使用中文语言属性CHINESE_VGRAM_LEXER进行索引

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

no rows selected

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

ID LANGUAG DOCS
---------- ------- -----------------------------------------------------------
4 But all the words is indexed by UPPER FORMAT.

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

ID LANGUAG DOCS
---------- ------- -----------------------------------------------------------
4 But all the words is indexed by UPPER FORMAT.

这就是说,对于包含多种语言的全文索引需要额外的小心。尤其是客户端的语言设置与全文索引中的非DEFAULT属性的SUB_LEXER的语言一致的情况。这个时候查询语句会仅返回当前语言下的索引记录。

0
0
查看评论

ORACLE TEXT LEXER PREFERENCE(二)

介绍完Oracle全文索引的BASIC_LEXER属性,这篇介绍Oracle中文语法属性CHINESE_LEXER和CHINESE_VGRAM_LEXER。 Oracle全文索引的BASIC属性主要是针对西方英语语系,英语语系的单词是通过空格、标点和回车来分隔的。而中文则需要索引来...
  • liqfyiyi
  • liqfyiyi
  • 2012-03-31 15:03
  • 716

ORACLE TEXT LEXER PREFERENCE(四)

本文继续介绍Oracle全文索引的LEXER属性,这篇文章介绍Oracle多语言全文索引DEFAULT_LEXER。 其实这篇文章应该放在LEXER属性的开头部分,不过我的测试一直和Oracle文档上的描述不符,所以一直没有写这篇文章,今天找了个环境又测试了一下,基本上可以...
  • liqfyiyi
  • liqfyiyi
  • 2012-03-31 15:05
  • 796

ORACLE TEXT LEXER PREFERENCE(一)

介绍完Oracle全文索引的FILTER属性,继续介绍Oracle的LEXER属性。 Oracle全文索引的LEXER属性用于处理各种不同的语言。最基本的英文使用BASE_FILTER,而如果需要使用中文则可以使用CHINESE_VGRAM_LEXER或CHINESE_LEXER。...
  • liqfyiyi
  • liqfyiyi
  • 2012-03-31 15:01
  • 786

ORACLE TEXT FILTER PREFERENCE(三)

这篇文章继续介绍全文索引的FILTER属性,介绍对不同类型的数据采用不同类型的FILTER属性的方法。 如果Oracle索引的文档包括多种类型,比如doc文件、html文件、pdf文件、纯文本文件等等。由于Oracle不建议对HTML、XML和纯文本文件使用INSO...
  • liqfyiyi
  • liqfyiyi
  • 2012-03-31 14:39
  • 548

ORACLE TEXT DATASTORE PREFERENCE(三)

这篇文章继续讨论全文索引的DATASTORE属性,介绍FILE_DATASTORE。 全文索引的对象一般是篇幅较大的文章,除了保存在数据库中的情况,另外一种常见的情况是以文件的形式保存在操作系统中。 Oracle的FILE_DATASTORE属性就可以索引这种类型的文...
  • liqfyiyi
  • liqfyiyi
  • 2012-03-31 14:26
  • 680

Oracle模糊查询之(5.1认识全文索引之什么是分词[lexer])oracle Text 全文检索功能对中文分词的支持情况

http://hi.baidu.com/lewutian 下面例子在XE中测试通过。 准备工作: CREATE   TABLE issues (     ID       &#...
  • haiross
  • haiross
  • 2013-10-23 17:00
  • 3158

ORACLE TEXT FILTER PREFERENCE(四)

这篇文章继续介绍全文索引的FILTER属性,介绍全文索引的PROCEDURE_FILTER属性。 对于一些复杂的需求,Oracle自定义的FILTER可能并不合适,Oracle支持用户自己编写用于FILTER的程序。Oracle提供两种方式,一种是USER_FILT...
  • liqfyiyi
  • liqfyiyi
  • 2012-03-31 14:59
  • 520

ORACLE TEXT DATASTORE PREFERENCE(二)

这篇文章继续讨论全文索引的DATASTORE属性,介绍MULTI_COLUMN_DATASTORE。 如果被索引的文章是保存在数据库中,但是内容分布在多个列中,那么可以通过建立一个MULTI_COLUMN_DATASTORE来索引完整的文章: SQL> CREATE T...
  • liqfyiyi
  • liqfyiyi
  • 2012-03-31 14:25
  • 1060

ORACLE TEXT DATASTORE PREFERENCE(一)

Oracle Text功能十分强大,可是文档上给出的例子总是过于简单,而且可能是为了减少篇幅,不少例子只给出了其中关键的几步,但是对于初学者而言,阅读这样的例子很难对全文索引的创建有一个清晰的了解,而更多的时候可能会使初学者更加迷茫。 打算通过一系列的文章对Oracle全文索引做一个比较详细的...
  • liqfyiyi
  • liqfyiyi
  • 2012-03-31 14:20
  • 667

ORACLE TEXT DATASTORE PREFERENCE(六)

这篇文章继续讨论全文索引的DATASTORE属性,介绍NESTED_DATASTORE。 全文索引支持将数据存储在多个列中或存储在主子表中,全文索引还支持将数据存储在嵌套表中。嵌套表的例子和主子表比较类似: 首先创建嵌套表对象,并建立嵌套表: SQL> C...
  • liqfyiyi
  • liqfyiyi
  • 2012-03-31 14:36
  • 553
    个人资料
    • 访问:2425283次
    • 积分:22134
    • 等级:
    • 排名:第393名
    • 原创:158篇
    • 转载:639篇
    • 译文:1篇
    • 评论:52条
    最新评论