这篇文章介绍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博客 ” ,链接:https://blog.itpub.net/271283/viewspace-1022445/
,如需转载,请注明出处,否则将追究法律责任。