您的位置:首页 > 数据库 > Oracle

oracle全文索引之STOPLIST

2010-01-08 14:43 288 查看
这篇文章开始介绍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的查询可以返回记录。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: