oracle全文索引之STOPLIST_4_MULTI_STOPLIST

jolly10發表於2009-05-26
這篇文章介紹Oracle全文索引的STOPLIST屬性。介紹的是MULTI_STOPLIST。[@more@]

上一篇文章中已經提到了,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的查詢可以返回記錄。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/271283/viewspace-1022482/,如需轉載,請註明出處,否則將追究法律責任。

相關文章