利用Oracle的全文索引實現切詞功能

yangtingkun發表於2008-01-30

今天在ITPUB上看到這樣一個需求,給出一箇中文語句,如何對其實現切詞。

如果Oracle全文索引的切詞可以滿足需求的話,那麼可以借用Oracle的功能來實現這個功能。

 

 

Oracle的全文索引本身具備中文分析、切詞功能,否則就無法有效的對中文進行搜尋,如果這個切詞結果可以滿足要求的話,那麼可以自己封裝一個函式,來借用Oracle的功能。

由於建立全文索引函式後,Oracle會將切詞結果放到DR$index_name$I表中,因此獲取這個表中的記錄就可以得到最終的切詞結果。

建立自定義函式的時候注意,由於這個操作包括很多DDL操作,因此如果希望這個函式可以在SQL中被呼叫,就必須使用自主事務。

為了方便的選擇CHINESE_LEXER還是CHINESE_VGRAM_LEXER,將MY_CHINESE_LEXER的建立放到了函式之外,這樣方便對切詞規則進行修改。這個過程也是唯一需要在建立自定義函式之前做的步驟。

下面是實現這個功能的建立的例子:

SQL> EXEC CTX_DDL.CREATE_PREFERENCE('MY_CHINESE_LEXER', 'CHINESE_VGRAM_LEXER')

PL/SQL 過程已成功完成。

SQL> CREATE OR REPLACE FUNCTION F_SPLIT_CHINESE(P_INPUT IN VARCHAR2) RETURN VARCHAR2 AS
  2   PRAGMA AUTONOMOUS_TRANSACTION; V_RETURN VARCHAR2(32767);
  3  BEGIN
  4   BEGIN
  5    EXECUTE IMMEDIATE 'DROP TABLE T_TEMP_TABLE PURGE';
  6   EXCEPTION
  7    WHEN OTHERS THEN
  8     NULL;
  9   END;
 10  
 11   EXECUTE IMMEDIATE 'CREATE TABLE T_TEMP_TABLE (STR VARCHAR2(4000))';
 12   EXECUTE IMMEDIATE 'INSERT INTO T_TEMP_TABLE VALUES (:STR)' USING P_INPUT;
 13   EXECUTE IMMEDIATE 'CREATE INDEX IND_T_TEMP_TABLE_STR ON T_TEMP_TABLE(STR) INDEXTYPE IS CTXSYS.CONTEXT
 14    PARAMETERS(''LEXER MY_CHINESE_LEXER'')';
 15   EXECUTE IMMEDIATE 'SELECT MAX(LTRIM(SYS_CONNECT_BY_PATH(TOKEN_TEXT, '',''), '',''))
 16    FROM
 17    (
 18     SELECT TOKEN_TEXT, ROW_NUMBER() OVER(ORDER BY TOKEN_TEXT) RN
 19     FROM DR$IND_T_TEMP_TABLE_STR$I
 20    )
 21    START WITH RN = 1
 22    CONNECT BY PRIOR RN + 1 = RN' INTO V_RETURN;
 23   EXECUTE IMMEDIATE 'DROP TABLE T_TEMP_TABLE PURGE';
 24   RETURN V_RETURN;
 25  END;
 26  /

函式已建立。

SQL> SELECT F_SPLIT_CHINESE('測試一下中文切詞') FROM DUAL;

F_SPLIT_CHINESE('測試一下中文切詞')
------------------------------------------------------------------------
測試,,切詞,試一,文切,下中,一下,中文

SQL> EXEC CTX_DDL.DROP_PREFERENCE('MY_CHINESE_LEXER')

PL/SQL 過程已成功完成。

SQL> EXEC CTX_DDL.CREATE_PREFERENCE('MY_CHINESE_LEXER', 'CHINESE_LEXER')

PL/SQL 過程已成功完成。

SQL> SELECT F_SPLIT_CHINESE('測試一下中文切詞') FROM DUAL;

F_SPLIT_CHINESE('測試一下中文切詞')
-----------------------------------------------------------------------
測試,,切詞,一下,中文

透過修改不同的LEXER語法,可以明顯的看出CHINESE_VGRAM_LEXERCHINESE_LEXER在中文分詞上的區別。關於二者區別的一些描述可以參考:http://yangtingkun.itpub.net/post/468/187632

需要注意的是,這個函式宣告瞭自主事務,雖然可以在SQL中呼叫,但是並不意味著這個函式不修改資料庫中的內容。

這個函式在呼叫的過程中會執行建表、建立索引、刪除表等一系列操作。因此呼叫這個函式的SELECT語句,不但會引起資料庫資料的變化,而且會導致DDL的發生,導致很多的遞迴呼叫、邏輯讀和REDO的產生。這是在使用這個函式之前需要理解的。

最後,這個函式在10g環境中完成,如果在9i版本使用,需要將DROP語句中的PURGE語句去掉,否則會造成語法錯誤。

 

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

相關文章