oracle全文索引之SECTION GROUP_1_NULL_SECTION_GROUP

jolly10發表於2009-05-25
這篇文章介紹Oracle全文索引的SECTION GROUP屬性中的NULL_SECTION_GROUP。[@more@]Oracle的全文索引的SECTION GROUP屬性用來支援包含內部結構的文件,比如HTML、XML文件等。使用了SECTION GROUP屬性,可以在查詢文件的時候指定在文件的哪一部分進行查詢。可以將查詢範圍限定在標題中。

這篇文章首先介紹最簡單的NULL_SECTION_GROUP,如果DATASTORE的屬性沒有設定為URL_DATASTORE且FILTER的屬性沒有設定為INSO_FILTER,則 NULL_SECTION_GROUP就是預設的SECTION_GROUP,否則HTML_SECTION_GROUP為預設 SECTION_GROUP。NULL_SECTION_GROUP的含義從名稱上已經可以看出,就是沒有設定SECTION GROUP,但Oracle還是提供了兩個預定義的SECTION:SENTENCE和PARAGRAPH。下面簡單介紹 NULL_SECTION_GROUP,並說明SENTENCE和PARAGRAPH的設定和使用。

SQL> conn myuser/myuser
Connected.
SQL> CREATE TABLE T (ID NUMBER, DOCS VARCHAR2(100));

Table created.

SQL> INSERT INTO T VALUES (1, 'A SIMPLE EXAMPLE FOR SECTION GROUP, TEST NULL_SECTION_GROUPATTRIBUTE.');

1 row created.

SQL> INSERT INTO T VALUES (2, 'THIS RECORD ONE, CAN BE QUERY IN NORNAL');

1 row created.

SQL> INSERT INTO T VALUES (3, 'THIS RECORD CAN BE QUERY IN SENTERNCE.');

1 row created.

SQL> INSERT INTO T VALUES (4, 'THIS RECORD
2 ARE TESTED FOR
3 THE QUERY IN PARAGRAPH');

1 row created.

SQL> COMMIT;

Commit complete.


SQL> CREATE INDEX IND_T_DOCS ON T(DOCS) INDEXTYPE IS CTXSYS.CONTEXT
2 PARAMETERS ('SECTION GROUP CTXSYS.NULL_SECTION_GROUP');

Index created.

建立一個NULL_SECTION_GROUP 屬性的索引很簡單,而且NULL_SECTION_GROUP不啟用節搜尋,因此查詢上也沒有什麼特殊的東西。但是NULL_SECTION_GROUP 可以支援Oracle預定義的兩種節搜尋,SENTENCE和PARAGRAPH,下面就簡單說明一下這兩個特性:

SQL> column docs format a50

SQL> SELECT * FROM T WHERE CONTAINS(DOCS, 'RECORD AND QUERY') > 0;

ID DOCS
---------- --------------------------------------------------
2 THIS RECORD ONE, CAN BE QUERY IN NORNAL
3 THIS RECORD CAN BE QUERY IN SENTERNCE.
4 THIS RECORD
ARE TESTED FOR
THE QUERY IN PARAGRAPH

SQL> SELECT * FROM T WHERE CONTAINS(DOCS, '(RECORD AND QUERY) WITHIN SENTENCE') > 0;
SELECT * FROM T WHERE CONTAINS(DOCS, '(RECORD AND QUERY) WITHIN SENTENCE') > 0
*
ERROR at line 1:
ORA-29902: error in executing ODCIIndexStart() routine
ORA-20000: Oracle Text error:
DRG-10837: section SENTENCE does not exist


SQL> SELECT * FROM T WHERE CONTAINS(DOCS, '(RECORD AND QUERY) WITHIN PARAGRAPH') > 0;
SELECT * FROM T WHERE CONTAINS(DOCS, '(RECORD AND QUERY) WITHIN PARAGRAPH') > 0
*
ERROR at line 1:
ORA-29902: error in executing ODCIIndexStart() routine
ORA-20000: Oracle Text error:
DRG-10837: section PARAGRAPH does not exist

在預設情況下,沒有設定這兩個節,因此相應的查詢語法會報錯:

SQL> DROP INDEX IND_T_DOCS;

Index dropped.


SQL> BEGIN
2 CTX_DDL.CREATE_SECTION_GROUP('TEST_NULL', 'NULL_SECTION_GROUP');
3 CTX_DDL.ADD_SPECIAL_SECTION('TEST_NULL', 'SENTENCE');
4 CTX_DDL.ADD_SPECIAL_SECTION('TEST_NULL', 'PARAGRAPH');
5 END;
6 /

SQL> CREATE INDEX IND_T_DOCS ON T(DOCS) INDEXTYPE IS CTXSYS.CONTEXT
2 PARAMETERS ('SECTION GROUP TEST_NULL');

Index created.

SQL> SELECT * FROM T WHERE CONTAINS(DOCS, 'RECORD AND QUERY') > 0;

ID DOCS
---------- --------------------------------------------------
2 THIS RECORD ONE, CAN BE QUERY IN NORNAL
3 THIS RECORD CAN BE QUERY IN SENTERNCE.
4 THIS RECORD
ARE TESTED FOR
THE QUERY IN PARAGRAPH


SQL> SELECT * FROM T WHERE CONTAINS(DOCS, '(RECORD AND QUERY) WITHIN SENTENCE') > 0;

ID DOCS
---------- --------------------------------------------------
2 THIS RECORD ONE, CAN BE QUERY IN NORNAL
3 THIS RECORD CAN BE QUERY IN SENTERNCE.
4 THIS RECORD
ARE TESTED FOR
THE QUERY IN PARAGRAPH


SQL> SELECT * FROM T WHERE CONTAINS(DOCS, '(RECORD AND QUERY) WITHIN PARAGRAPH') > 0;

ID DOCS
---------- --------------------------------------------------
2 THIS RECORD ONE, CAN BE QUERY IN NORNAL
3 THIS RECORD CAN BE QUERY IN SENTERNCE.
4 THIS RECORD
ARE TESTED FOR
THE QUERY IN PARAGRAPH

透過在自定義SECTION GROUP TEST_NULL中設定SENTENCE和PARAGRAPH,使得查詢中的節搜尋語法順利執行。但是查詢的結果卻和我預想的有很大的出入。
這是由於SENTENCE和PARAGRAPH是Oracle預定義的節組,節組預定義的規則完全由FILTER引數控制。因此,不同格式的文章甚至是相同格式不同語言的文件的節屬性也都不相同。

經過一系列的測試發現,中文WORD文件的SENTENCE和PARAGRAPH節搜尋還是比較好理解的,下面透過一個簡單的例子進行說明。

首先,重建測試用表:

SQL> DROP TABLE T;

表已丟棄。

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

表已建立。

SQL> INSERT INTO T VALUES (1, 'TEST.DOC');

已建立 1 行。

SQL> COMMIT;

提交完成。

SQL> CONN CTXSYS/CTXSYS@YANGTK
已連線。
SQL> BEGIN
2 CTX_DDL.CREATE_PREFERENCE('TEST_FILE', 'FILE_DATASTORE');
3 CTX_DDL.SET_ATTRIBUTE('TEST_FILE', 'PATH', 'F:');
4 CTX_DDL.CREATE_PREFERENCE('TEST_CHINESE_VGRAM_LEXER', 'CHINESE_VGRAM_LEXER');
5 END;
6 /

PL/SQL 過程已成功完成。

SQL> CONN YANGTK/YANGTK@YANGTK
已連線。
SQL> CREATE INDEX IND_T_DOCS ON T(DOCS) INDEXTYPE IS CTXSYS.CONTEXT
2 PARAMETERS ('DATASTORE CTXSYS.TEST_FILE FILTER CTXSYS.INSO_FILTER
3 LEXER CTXSYS.TEST_CHINESE_VGRAM_LEXER SECTION GROUP CTXSYS.TEST_NULL');

索引已建立。

索引建立好了,在查詢之前,首先看一下被索引文件TEST.DOC的內容:

--------------------------------------------------------------------------------------------------

這個例子

可以被

行節查詢到。

上面的內容和當前的內容,都可以被段節訪問到。

--------------------------------------------------------------------------------------------------

上面兩條分隔線之間的內容就是被索引的文件。Oracle認為中文的WORD文件中前三行記錄屬於一個SENTENCE,裡面的內容可以被SENTENCE節搜尋查詢到。而上面的三行和最後的一行中的內容只能透過PARAGRAPH節搜尋查詢到。

SQL> SELECT * FROM T WHERE CONTAINS(DOCS, '例子 AND 查詢') > 0;

ID DOCS
---------- ------------------------------
1 TEST.DOC

SQL> SELECT * FROM T WHERE CONTAINS(DOCS, '(例子 AND 查詢) WITHIN SENTENCE') > 0;

ID DOCS
---------- ------------------------------
1 TEST.DOC

SQL> SELECT * FROM T WHERE CONTAINS(DOCS, '(例子 AND 查詢) WITHIN PARAGRAPH') > 0;

ID DOCS
---------- ------------------------------
1 TEST.DOC

SQL> SELECT * FROM T WHERE CONTAINS(DOCS, '例子 AND 訪問') > 0;

ID DOCS
---------- ------------------------------
1 TEST.DOC

SQL> SELECT * FROM T WHERE CONTAINS(DOCS, '(例子 AND 訪問) WITHIN SENTENCE') > 0;

未選定行

SQL> SELECT * FROM T WHERE CONTAINS(DOCS, '(例子 AND 訪問) WITHIN PARAGRAPH') > 0;

ID DOCS
---------- ------------------------------
1 TEST.DOC

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

相關文章