oracle全文索引之STOPLIST

这篇文章开始介绍Oracle全文索引的STOPLIST属性。首先介绍的是BASIC_STOPLIST。
Oracle的全文索引允许用户建立停用词,来屏蔽那些包含信息量比较小且出现概率比较高的词语。

比如英文中的a、this、are、the等词语,几乎每篇文章中都会包含这些常用词,因此对这些词语进行索引的意义不大。

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

表已创建。

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

Table created.

SQL> INSERT INTO T VALUES (1, 'THIS IS A STOPLIST EXAMPLE.');

1 row created.

SQL> COMMIT;

Commit complete.


SQL> exec CTX_DDL.CREATE_STOPLIST('TEST_BASIC', 'BASIC_STOPLIST');

PL/SQL procedure successfully completed.

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

Index created.

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


ID DOCS
---------- ------------------------------
1 THIS IS A STOPLIST EXAMPLE.


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

ID DOCS
---------- ------------------------------
1 THIS IS A STOPLIST EXAMPLE.

建立了一个BASIC_STOPLIST后,由于并没有添加停用词,这个BASIC_STOPLIST停用词表是空的。这个时候不会屏蔽任何词语。

SQL> exec CTX_DDL.ADD_STOPWORD('TEST_BASIC', 'A');

PL/SQL procedure successfully completed.

SQL> drop index IND_T_DOCS
2 ;

Index dropped.

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

Index created.

SQL> SELECT * FROM T WHERE CONTAINS(DOCS, 'EXAMPLE') > 0;
ID DOCS
---------- ------------------------------
1 THIS IS A STOPLIST EXAMPLE.


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

no rows selected


在上面的例子中,将单词’a’添加到了停用词表中,重新建立索引后,发现停用词已经生效。

 

这篇文章介绍Oracle全文索引的STOPLIST属性。介绍的是EMPTY_STOPLIST。


如果索引的文章比较短小,或者认为文章中所有的内容都是关键性的,那么可以选择EMPTY_STOPLIST。使用EMPTY_STOPLIST表示系统中不包含任何的停用词,只要文章中出现的单词,都是可以索引到的。

下面看个简单的例子,对于默认停用词‘THIS’和‘A’,使用默认的停用词无法查询到这些信息,只有使用EMPTY_STOPLIST才行。

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

表已创建。

SQL> INSERT INTO T VALUES (1, 'This is a simple stoplist example.');

已创建 1 行。

SQL> INSERT INTO T VALUES (2, 'This example is about to empty_stoplist.');

已创建 1 行。

SQL> COMMIT;

提交完成。

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

索引已创建。

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

ID DOCS
---------- --------------------------------------------------
1 This is a simple stoplist example.

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

未选定行

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

未选定行

SQL> DROP INDEX IND_T_DOCS;

索引已丢弃。

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

索引已创建。

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

ID DOCS
---------- --------------------------------------------------
1 This is a simple stoplist example.

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

ID DOCS
---------- --------------------------------------------------
1 This is a simple stoplist example.

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

ID DOCS
---------- --------------------------------------------------
2 This example is about to empty_stoplist.
1 This is a simple stoplist example.

例子十分简单,就不再详细描述了。

 

这篇文章介绍Oracle全文索引的STOPLIST属性。介绍的是DEFAULT_STOPLIST。


Oracle 的DEFAULT_STOPLIST和其他属性的DEFAULT值不太一样。一般的属性的DEFAULT值都会指向一个已经存在的属性值,比如 DEFAULT_DATASTORE指向DIRECT_DATASTORE,DEFAULT_FILTER会根据DATASTORE属性和字段类型的不同 指向NULL_FILTER或INSO_FILTER。而DEFAULT_STOPLIST和上述这些属性都有一定的差别。 DEFAULT_STOPLIST指向BASIC_STOPLIST,但是DEFAULT_STOPLIST并不等于BASIC_STOPLIST,在介 绍BASIC_STOPLIST的时候已经发现,创建一个BASIC_STOPLIST后,并不包含任何的停用词。而DEFAULT_STOPLIST在 BASIC_STOPLIST的基础上增加了预定义的默认停用词。而且,对于不同的情况,默认的停用词的语言也不相同。

根据测试发现,DEFAULT_LEXER决定默认的停用词的语言。也就是说,默认停用词的语言对于一个数据库是确定的。在Oracle9i中,默认同义词只包含英文默认停用词:


参考http://yangtingkun.itpub.net/post/468/200217

这篇文章介绍Oracle全文索引的STOPLIST属性。介绍的是MULTI_STOPLIST。

上一篇文章中已经提到了,DEFAULT_STOPLIST的语言是由DEFAULT_LEXER决定的。Oracle对于多语言的文档支持MULTI_LEXER,同时也支持MULTI_STOPLIST。

在增加同义词的时候,可以为某个停用词指定语言,这个停用词就只对指定的语言生效。而默认不指定语言的情况,则对任何语言都生效。

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

表已创建。

SQL> INSERT INTO T VALUES (1, 'ENGLIST', 'THIS IS A MULTI_STOPLIST EXAMPLE.');

已创建 1 行。

SQL> INSERT INTO T VALUES (2, 'CHINESE', '这个例子是多语言停用词的自理。');

已创建 1 行。

SQL> INSERT INTO T VALUES (3, 'ENGLIST', 'TO USE MULTI_STOPLIST FIRST USE MULTI_LEXER.');

已创建 1 行。

SQL> INSERT INTO T VALUES (4, 'CHINESE', '使用多语言停用词首先要使用多语言LEXER。');

已创建 1 行。

SQL> COMMIT;

提交完成。

SQL> CONN CTXSYS/CTXSYS@YANGTK
已连接。
SQL> BEGIN
2 CTX_DDL.CREATE_PREFERENCE('TEST_CHINESE_VGRAM', '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_VGRAM');

索引已创建。

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

ID LANGUAG DOCS
---------- ------- --------------------------------------------------
4 CHINESE 使用多语言停用词首先要使用多语言LEXER。
3 ENGLIST TO USE MULTI_STOPLIST FIRST USE MULTI_LEXER.

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

ID LANGUAG DOCS
---------- ------- --------------------------------------------------
4 CHINESE 使用多语言停用词首先要使用多语言LEXER。

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

未选定行

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

ID LANGUAG DOCS
---------- ------- --------------------------------------------------
4 CHINESE 使用多语言停用词首先要使用多语言LEXER。
2 CHINESE 这个例子是多语言停用词的自理。

SQL> DROP INDEX IND_T_DOCS;

索引已丢弃。

上面是不指定停用词的情况,如果将‘LEXER’添加的默认停用词中,则会同时影响记录3和记录4。

SQL> CONN CTXSYS/CTXSYS@YANGTK
已连接。
SQL> BEGIN
2 CTX_DDL.ADD_STOPWORD('DEFAULT_STOPLIST', '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_VGRAM');

索引已创建。

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

未选定行

SQL> DROP INDEX IND_T_DOCS;

索引已丢弃。

而如果建立了MULTI_STOPLIST,并在增加STOPWORD的时候指定语言,则停用词只对指定的语言生效。

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_VGRAM_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 CTX_DDL.CREATE_STOPLIST('TEST_MULTI', 'MULTI_STOPLIST');
9 CTX_DDL.ADD_STOPWORD('TEST_MULTI', 'LEXER', 'ENGLISH');
10 CTX_DDL.ADD_STOPWORD('TEST_MULTI', '首先', 'SIMPLIFIED CHINESE');
11 END;
12 /

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 STOPLIST CTXSYS.TEST_MULTI');

索引已创建。

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

ID LANGUAG DOCS
---------- ------- --------------------------------------------------
4 CHINESE 使用多语言停用词首先要使用多语言LEXER。
3 ENGLIST TO USE MULTI_STOPLIST FIRST USE MULTI_LEXER.

SQL> ALTER SESSION SET NLS_LANGUAGE = 'ENGLISH';

Session altered.

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

no rows selected

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

ID LANGUAG DOCS
---------- ------- --------------------------------------------------
1 ENGLIST THIS IS A MULTI_STOPLIST EXAMPLE.

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

会话已更改。

SQL> SELECT * FROM T WHERE CONTAINS(DOCS, '首先') > 0;
SELECT * FROM T WHERE CONTAINS(DOCS, '首先') > 0
*
ERROR 位于第 1 行:
ORA-29902: 执行 ODCIIndexStart() 例行程序中出错
ORA-20000: Oracle Text error:
DRG-10817: CONTAINS 搜索词包含禁用词或禁用词的词组: 首先


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

ID LANGUAG DOCS
---------- ------- -------------------------------------------------
4 CHINESE 使用多语言停用词首先要使用多语言LEXER。
2 CHINESE 这个例子是多语言停用词的自理。

可以看到,由于LEXER 被添加到英文的停用词中,因此,使用中文环境进行查询的时候是可以查询到记录的,而将环境切换到ENGLISH语言中,则无法查询到记录,说明停用词只对 英语有效。这里需要注意的是,由于定义的时候指定的是ENGLISH,则切换环境的时候也要切换到ENGLISH,DEFAULT_STOPLIST和 DEFAULT_LEXER不同,如果将语言切换为AMERICAN,则LEXER属性可以兼容并继续工作,而定义在ENGLISH语言中的停用词对 AMERICAN环境无效。

最后由于TEST_MULTI是用户定义的停用词,不包含系统默认的停用词,因此对THIS的查询可以返回记录。

 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值