oracle全文索引之停用詞的萬用字元功能

jolly10發表於2009-05-29
全文索引停用詞的設定在前面的文章中已經介紹過了,這裡簡單說明記錄一下停用詞在查詢時候需要注意的地方。[@more@]Oracle10g中,如果安裝語言為中文,預設的LEXER為CHINESE_VGRAM_LEXER,預設的停用詞語言也為中文。這篇透過對比中文環境和英文環境來說明停用詞查詢的一些特點。

SQL> show user
USER is "MYUSER"
SQL> CREATE TABLE T (ID NUMBER, DOCS VARCHAR2(1000));

Table created.

SQL> INSERT INTO T VALUES (1, 'This example test stopword.');

1 row created.

SQL> INSERT INTO T VALUES (2, 'Oracle9i chinese language environment default stopword are english.');

1 row created.

SQL> COMMIT;

Commit complete.

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

Index created.

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

no rows selected


英文環境下允許單獨查詢停用詞,但是不會返回結果。

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

ID DOCS
--- --------------------------------------------------
2 Oracle9i chinese language environment default stop
word are english.


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

ID DOCS
--- --------------------------------------------------
2 Oracle9i chinese language environment default stop
word are english.


SQL> SELECT * FROM T WHERE CONTAINS(DOCS, 'stopword are english') > 0;

ID DOCS
--- --------------------------------------------------
2 Oracle9i chinese language environment default stop
word are english.


SQL> SELECT * FROM T WHERE CONTAINS(DOCS, 'stopword is english') > 0;

ID DOCS
--- --------------------------------------------------
2 Oracle9i chinese language environment default stop
word are english.


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

ID DOCS
--- --------------------------------------------------
1 This example test stopword.
2 Oracle9i chinese language environment default stop
word are english.

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

ID DOCS
--- --------------------------------------------------
1 This example test stopword.


上面這些查詢,由於are、is都是停用詞,因此可以認為是一個替代符,代替任何單詞。而且查詢語句中包含的停用詞不僅可以替代文件中本身的停用詞,還可以替代任何有意義的單詞,如上面對ARE STOPWORD的查詢分別對應了DEFAULT STOPWORD和TEST STOPWORD



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

no rows selected

SQL> SELECT * FROM T WHERE CONTAINS(DOCS, 'default is stopword') > 0;

no rows selected

最後兩個查詢說明停用詞雖然可以替換任何詞,但是無論是文件中的停用詞還是查詢語句中包含的停用詞,對必須對應一個單詞,如果直接將停用詞所在位置的單詞忽略掉是不會返回結果的。僅這一點上,停用詞有點像萬用字元“_”。

SQL> SELECT * FROM V$VERSION;

BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod
PL/SQL Release 10.2.0.1.0 - Production
CORE 10.2.0.1.0 Production
TNS for Linux: Version 10.2.0.1.0 - Production
NLSRTL Version 10.2.0.1.0 - Production


下面是中文環境的測試

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

表已建立。

SQL> INSERT INTO T VALUES (1, '這個例子測試停用詞');

已建立 1 行。

SQL> INSERT INTO T VALUES (2, 'Oracle10g中文環境預設也是中文');

已建立 1 行。

SQL> COMMIT;

提交完成。

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

索引已建立。

SQL> SELECT * FROM T WHERE CONTAINS(DOCS, '這個') > 0;
SELECT * FROM T WHERE CONTAINS(DOCS, '這個') > 0
*第 1 行出現錯誤:
ORA-29902: 執行 ODCIIndexStart() 例行程式中出錯
ORA-20000: Oracle Text error:
DRG-10817: CONTAINS 搜尋詞包含禁用詞或禁用詞的片語: 這個對於中文環境,如果查詢只包含停用詞,那麼查詢會報錯,這一點和英文環境明顯不同。

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

ID DOCS
---------- --------------------------------------------------
2 Oracle10g中文環境預設也是中文

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

ID DOCS
---------- --------------------------------------------------
2 Oracle10g中文環境預設也是中文

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

ID DOCS
---------- --------------------------------------------------
2 Oracle10g中文環境預設也是中文

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

未選定行

由於“也是”、“就是”和“還是”都是停用詞,索引查詢2到查詢4都可以返回結果。但是“不是”不屬於停用詞,因此,透過不是查詢無法返回結果。這個測試和英文停用詞的測試很像。

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

ID DOCS
---------- --------------------------------------------------
2 Oracle10g中文環境預設也是中文

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

未選定行

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

未選定行

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

未選定行

這次在查詢語句中,停用詞兩邊都包含了內容,這時候發現停用詞似乎沒有起作用,只有全文匹配的查詢生效了。感覺是由於中文的切詞要比英文複雜,因此不好判斷查詢短語中是否包含了停用詞。


SQL> SELECT * FROM T WHERE CONTAINS(DOCS, '環境預設') > 0;

ID DOCS
---------- ----------------------------------------------------------
2 Oracle10g中文環境預設也是中文

SQL> SELECT * FROM T WHERE CONTAINS(DOCS, '也是預設') > 0;

未選定行

兩個查詢也說明了中文和英文環境的不同。中文環境中,查詢語句中的停用詞似乎只能替換停用詞,而不能再替換其他有意義的詞彙了。

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

未選定行


最後一個查詢和英文環境一致,停用詞必須佔一個詞的位置。

SQL> SELECT * FROM V$VERSION;

BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod
PL/SQL Release 10.2.0.1.0 - Production
CORE 10.2.0.1.0 Production
TNS for 32-bit Windows: Version 10.2.0.1.0 - Production
NLSRTL Version 10.2.0.1.0 - Production

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

相關文章