oracle全文索引之datastore

来源:互联网 发布:局域网监控系统java 编辑:程序博客网 时间:2024/06/10 15:19

 

Oracle Text功能十分强大,开始学习,主要参考yangtingkun的blog和文档进行。

第一步先搞清楚datastore的类型。


DATASTORE的类型如下:

DIRECT_DATASTORE
MULTI_COLUMN_DATASTORE
DETAIL_DATASTORE
FILE_DATASTORE
NESTED_DATASTORE
URL_DATASTORE
USER_DATASTORE

下面就各种类型进行测试,DIRECT_DATASTORE是最简单的,默认是就是用这种类型

Oracle的全文索引不要求被索引的文章一定存储在数据库中,不过如果文章存储在数据库的一列中,那么这种情

况建立索引是最简单的。

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

表已创建。

SQL> INSERT INTO T VALUES (1, 'This is a sample for Oracle TEXT.');

已创建 1 行。

SQL> INSERT INTO T VALUES (2, 'This is a direct database store sample');

已创建 1 行。

SQL> COMMIT;

提交完成。

对于上面提到的DIRECT DATASTORE类型,下面三种创建索引方式是等价的:

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

索引已创建。

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

ID DOCS
---------- ----------------------------------------
2 This is a direct database store sample

SQL> DROP INDEX IND_T_DOCS;

索引已丢弃。

SQL> CREATE INDEX IND_T_DOCS ON T (DOCS) INDEXTYPE IS CTXSYS.CONTEXT
2 PARAMETERS ('DATASTORE CTXSYS.DEFAULT_DATASTORE');

索引已创建。

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

ID DOCS
---------- ----------------------------------------
2 This is a direct database store sample

SQL> DROP INDEX IND_T_DOCS;

索引已丢弃。

SQL> CREATE INDEX IND_T_DOCS ON T (DOCS) INDEXTYPE IS CTXSYS.CONTEXT
2 PARAMETERS ('DATASTORE CTXSYS.DIRECT_DATASTORE');

索引已创建。

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

ID DOCS
---------- ----------------------------------------
2 This is a direct database store sample

上面给出了一个最简单的全文索引的例子。

另外,由DR$开头的4张表是系统为了支持全文索引而自动生成的,不过这4张表的用处就不再这里讨论了。

SQL> SELECT * FROM TAB;

TNAME TABTYPE CLUSTERID
------------------------------ ------- ----------
DR$IND_T_DOCS$I TABLE
DR$IND_T_DOCS$K TABLE
DR$IND_T_DOCS$N TABLE
DR$IND_T_DOCS$R TABLE

 

继续讨论全文索引的DATASTORE属性,介绍MULTI_COLUMN_DATASTORE。

如果被索引的文章是保存在数据库中,但是内容分布在多个列中,那么可以通过建立一个MULTI_COLUMN_DATASTORE来索引完整的文章:

SQL> CREATE TABLE T (ID NUMBER, DOC1 VARCHAR2(4000), DOC2 VARCHAR2(4000), DOC3 VARCHAR2(4000));

表已创建。

SQL> INSERT INTO T VALUES (1,
2 'The first paragraph of article in doc1.',
3 'The second partments is the doc2.',
4 'The last content is in the doc3.');

已创建 1 行。

SQL> INSERT INTO T VALUES (2,
2 'This example create a multi-column datastore preference',
3 'called test_multicol on three text columns',
4 'to be concatenated and indexed.');

已创建 1 行。

SQL> COMMIT;

提交完成。

下面创建索引,由于需要建立一个多列存储的全文索引,需要将多个列的列名作为参数传给Oracle。这个过程通过建立一个PREFERENCE,并设置属性来完成。

注意,下面的代码需要由CTXSYS用户执行,这点是文档上没有明确说明的。

SQL> CONN CTXSYS/CTXSYS@YANGTK
已连接。
SQL> BEGIN
2 CTX_DDL.CREATE_PREFERENCE('TEST_MULTICOL', 'MULTI_COLUMN_DATASTORE');
3 CTX_DDL.SET_ATTRIBUTE('TEST_MULTICOL', 'COLUMNS', 'DOC1, DOC2, DOC3');
4 END;
5 /

PL/SQL 过程已成功完成。

下面在建立索引的时候指定DATASTORE参数为新建的TEST_MULTICOL参数:

SQL> CONN YANGTK/YANGTK@YANGTK
已连接。
SQL> CREATE INDEX IND_T_DOCS ON T (DOC1) INDEXTYPE IS CTXSYS.CONTEXT
2 PARAMETERS ('DATASTORE CTXSYS.TEST_MULTICOL');

索引已创建。

SQL> SELECT * FROM T WHERE CONTAINS(DOC1, 'CONTENT') > 0;

ID
----------
DOC1
---------------------------------------------------------------------------
DOC2
---------------------------------------------------------------------------
DOC3
---------------------------------------------------------------------------
1
The first paragraph of article in doc1.
The second partments is the doc2.
The last content is in the doc3.

通过查询的结果可以发现,这个多列的全文索引已经生效。

SQL> SELECT * FROM T WHERE CONTAINS(DOC2, 'CONTENT') > 0;
SELECT * FROM T WHERE CONTAINS(DOC2, 'CONTENT') > 0
*
ERROR 位于第 1 行:
ORA-20000: Oracle Text error:
DRG-10599: 列没有编制索引


SQL> CREATE INDEX IND_T_DOCS2 ON T (DOC2) INDEXTYPE IS CTXSYS.CONTEXT
2 PARAMETERS ('DATASTORE CTXSYS.TEST_MULTICOL');

索引已创建。

SQL> SELECT * FROM T WHERE CONTAINS(DOC2, 'CONTENT') > 0;

ID
----------
DOC1
----------------------------------------------------------------------------
DOC2
----------------------------------------------------------------------------
DOC3
----------------------------------------------------------------------------
1
The first paragraph of article in doc1.
The second partments is the doc2.
The last content is in the doc3.

通过上面的例子可以看出,对于多列的全文索引可以建立在多个列的任意一列上,但是,在查询时指定的列必须与索引时指定的列保持一致。

最后注意一点,只有索引指定的列发生修改,Oracle才会认为被索引数据发生了变化,仅仅修改其他列而没有修改索引列,即使同步索引也不会将修改同步到索引中。

SQL> DROP INDEX IND_T_DOCS2;

索引已丢弃。

SQL> SELECT * FROM CTX_USER_PENDING;

未选定行

SQL> UPDATE T SET COL3 = NULL WHERE ID = 1;
UPDATE T SET COL3 = NULL WHERE ID = 1
*
ERROR 位于第 1 行:
ORA-00904: "COL3": 无效的标识符


SQL> UPDATE T SET DOC3 = NULL WHERE ID = 1;

已更新 1 行。

SQL> SELECT * FROM CTX_USER_PENDING;

未选定行

SQL> UPDATE T SET DOC1 = NULL WHERE ID = 1;

已更新 1 行。

SQL> SELECT * FROM CTX_USER_PENDING;

PND_INDEX_NAME PND_PARTITION_NAME PND_ROWID PND_TIMEST
-------------------------- ------------------ ------------------ ----------
IND_T_DOCS AAAJXiAAMAAAAAGAAA 25-7月 -06

 

DATASTORE是FILE_DATASTORE的测试
[oracle@rhel140 ~]$ cat OUTPUT.TXT
ORACLE
oracle

[oracle@rhel140 LOG]$ cat EMPXT_000_2012_2680.LOG
SOURCE
ABC


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

Table created.

SQL> INSERT INTO T VALUES (1, 'OUTPUT.TXT');

1 row created.

SQL> commit;

Commit complete.


SQL> BEGIN
2 CTX_DDL.CREATE_PREFERENCE('TEST_FILE', 'FILE_DATASTORE');
3 CTX_DDL.SET_ATTRIBUTE('TEST_FILE', 'PATH', '/home/oracle');
4 END;
5 /

PL/SQL procedure successfully completed.

SQL> CREATE INDEX IND_T_DOCS ON T (DOCS) INDEXTYPE IS CTXSYS.CONTEXT
PARAMETERS ('DATASTORE TEST_FILE'); 2

Index created.

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

ID DOCS
---- --------------------
1 OUTPUT.TXT


需要注意的是在建立PREFERENCE的PATH属性时不能用客户端的目录和文件,一定是服务器端的目录和文件,
我用WINDOWS的目录时,在dr$index_error中就会出现下面的错误
SQL> select * from ctxsys.dr$index_error;

ERR_IDX_ID ERR_TIMES ERR_TEXTKEY
---------- --------- ------------------
ERR_TEXT
--------------------------------------------------------------------------------
1181 13-MAY-09 AAAM52AAEAAAAGkAAA
DRG-11513: unable to open or write to file /home/oracle/OUTPUT.TXT


SQL> INSERT INTO T VALUES (2, 'LOG/EMPXT_000_2012_2680.LOG');

1 row created.

SQL> commit;

Commit complete.

SQL> exec CTX_DDL.SYNC_INDEX('IND_T_DOCS');

PL/SQL procedure successfully completed.

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

no rows selected

Oracle似乎只支持在FILE_DATASTORE中设置的路径中进行搜索,即使像上面这个例子中第2条记录,文档存储在

指定路径下的子目录中,这种情况也是没有办法进行索引的。

如果将文件位置从/home/oracle/LOG挪到/home/oracle目录下,则可以进行索引:

SQL> host mv /home/oracle/LOG/EMPXT_000_2012_2680.LOG /home/oracle

SQL> UPDATE T SET DOCS = 'EMPXT_000_2012_2680.LOG' WHERE ID = 2;

1 row updated.

SQL> COMMIT;

Commit complete.

SQL> exec CTX_DDL.SYNC_INDEX('IND_T_DOCS');

PL/SQL procedure successfully completed.

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

ID
----------
DOCS
--------------------------------------------------------------------------------
2
EMPXT_000_2012_2680.LOG

测试还发现,只要将文件置于/home/oracle目录下即可,即使DOCS中存储的文件位置是子目录的信息。
下面不改变文件的存储位置,只是修改保存在数据库中的文档的地址:

SQL> UPDATE T SET DOCS = 'LOG/EMPXT_000_2012_2680.LOG' WHERE ID = 2;

1 row updated.

SQL> commit;

Commit complete.

SQL> exec CTX_DDL.SYNC_INDEX('IND_T_DOCS');

PL/SQL procedure successfully completed.

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

ID
----------
DOCS
--------------------------------------------------------------------------------
2
LOG/EMPXT_000_2012_2680.LOG

看yangtingkun的实验是可以在一个PATH里指定多少目录,但我试了是不行的,不知是为什么

SQL> host mv /home/oracle/EMPXT_000_2012_2680.LOG /home/oracle/LOG/EMPXT_000_2012_2680.LOG

SQL> exec CTX_DDL.DROP_PREFERENCE('TEST_FILE');

PL/SQL procedure successfully completed.

SQL> BEGIN
2 CTX_DDL.CREATE_PREFERENCE('TEST_FILE', 'FILE_DATASTORE')
3 CTX_DDL.CREATE_PREFERENCE('TEST_FILE', 'FILE_DATASTORE')


SQL> BEGIN
2 CTX_DDL.CREATE_PREFERENCE('TEST_FILE', 'FILE_DATASTORE');
3 CTX_DDL.SET_ATTRIBUTE('TEST_FILE', 'PATH', '/home/oracle;/home/oracle/LOG');
4 end;
5 /

PL/SQL procedure successfully completed.

SQL> DROP INDEX IND_T_DOCS;

Index dropped.

SQL> CREATE INDEX IND_T_DOCS ON T (DOCS) INDEXTYPE IS CTXSYS.CONTEXT
2 PARAMETERS ('DATASTORE TEST_FILE');

Index created.

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

no rows selected

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

no rows selected

表ctxsys.dr$index_error的错误如下,就是找不到目录

[oracle@rhel140 LOG]$ sqlplus ctxsys/ctxsys

SQL> select * from ctxsys.dr$index_error;

ERR_IDX_ID ERR_TIMES ERR_TEXTKEY
---------- --------- ------------------
ERR_TEXT
--------------------------------------------------------------------------------
1261 14-MAY-09 AAAM6dAAEAAAAG+AAA
DRG-11513: unable to open or write to file /home/oracle;/home/oracle/LOG/OUTPUT.
TXT

1261 14-MAY-09 AAAM6dAAEAAAAG/AAA
DRG-11513: unable to open or write to file /home/oracle;/home/oracle/LOG/EMPXT_0
00_2012_2680.LOG

 

 

 

全文索引可以很方便的索引存储在INTERNET上的信息。在数据库中只需要存储需要索引的文章的URL就可以了。

由于目前讨论的是DATASTORE属性,因此这个例子只索引HTML文章,对于其他需要使用FILTER属性的文章,在以后讨论。

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

Table created.

SQL> INSERT INTO T VALUES (1, 'http://yangtingkun.itpub.net/');

1 row created.

SQL> INSERT INTO T VALUES (2, 'http://www.itpub.net/');

1 row created.

SQL> COMMIT;

Commit complete.

SQL> exec CTX_DDL.CREATE_PREFERENCE('TEST_URL', 'URL_DATASTORE');

PL/SQL procedure successfully completed.


SQL> exec ctx_ddl.set_attribute('TEST_URL','HTTP_PROXY','172.17.61.29:8002');

PL/SQL procedure successfully completed.

SQL> exec ctx_ddl.set_attribute('TEST_URL','Timeout','300');

PL/SQL procedure successfully completed.

SQL> CREATE INDEX IND_T_DOCS ON T (DOCS) INDEXTYPE IS CTXSYS.CONTEXT
2 PARAMETERS ('DATASTORE TEST_URL');

Index created.

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

no rows selected


由于公司上网需要设置代理,发现设置了proxy服务器的IP地址和port不行,必须要指定为proxy服务的机器名和port.

如果需要代理才能连到INTERNET上,可以设置URL_DATASTORE的HTTP_PROXY等属性。URL_DATASTORE还包含很多的属性

Attribute Attribute Values
timeout
Specify the timeout in seconds. The valid range is 15 to 3600 seconds. The default is 30.

maxthreads
Specify the maximum number of threads that can be running simultaneously. Use a number between

1and 1024. The default is 8.

urlsize
Specify the maximum length of URL string in bytes. Use a number between 32 and 65535. The default

is 256.

maxurls
Specify maximum size of URL buffer. Use a number between 32 and 65535. The defaults is 256.

maxdocsize
Specify the maximum document size. Use a number between 256 and 2,147,483,647 bytes (2

gigabytes). The defaults is 2,000,000.

http_proxy
Specify the host name of http proxy server. Optionally specify port number with a colon in the

form hostname:port.

ftp_proxy
Specify the host name of ftp proxy server. Optionally specify port number with a colon in the

form hostname:port.

no_proxy
Specify the domain for no proxy server. Use a comma separated string of up to 16 domain names.



最后要说明的是,Oracle中仅仅保存被索引文档的URL地址,因此,如果文档本身发生了变化,Oracle是无法知道的,也无法去同步索引,这时必须通过修改索引列也就是URL地址列的方式来通知Oracle,被索引数据已经发生了变化。

 

 

 

这篇文章继续讨论全文索引的DATASTORE属性,介绍DETAIL_DATASTORE。

 

全文索引运行将被索引的数据存储在子表的多条记录中,下面看一个简单的例子:

SQL> CREATE TABLE T (ID NUMBER PRIMARY KEY, AUTHER VARCHAR2(30), TITLE VARCHAR2(30));

Table created.

SQL> CREATE TABLE T1 (ID NUMBER PRIMARY KEY, FID NUMBER, SEQ NUMBER, DOCS VARCHAR2(1000),
2 CONSTRAINT FK_T1_FID FOREIGN KEY (FID) REFERENCES T(ID))
3 ;

Table created.

SQL> INSERT INTO T VALUES (1, 'YTK', 'DETAIL DATASTORE');

1 row created.

SQL> INSERT INTO T1 VALUES (1, 1, 1, 'THIS IS A DETAIL DATASTORE EXAMPLE');

1 row created.

SQL> INSERT INTO T1 VALUES (2, 1, 2, 'THE CONTEXT IS STORE IN DETAIL TABLES');

1 row created.

SQL> INSERT INTO T VALUES (2, 'YTK', 'DETAIL DATASTORE DOC');

1 row created.

SQL> INSERT INTO T1 VALUES (3, 2, 1, 'USE THE DETAIL_DATASTORE TYPE FOR TEXT');

1 row created.

SQL> INSERT INTO T1 VALUES (4, 2, 2, 'STORED DEIRECTLY IN THE DATABASE IN DETAIL TABLES');

1 row created.

SQL> INSERT INTO T1 VALUES (5, 2, 3, 'WITH INDEXED TEXT COLUMN');

1 row created.

SQL> INSERT INTO T1 VALUES (6, 2, 4, 'LOCATED IN THE MASTER TABLE');

1 row created.

SQL> commit;

Commit complete.

SQL> BEGIN
2 CTX_DDL.CREATE_PREFERENCE('TEST_DETAIL', 'DETAIL_DATASTORE');
3 CTX_DDL.SET_ATTRIBUTE('TEST_DETAIL', 'BINARY', 'TRUE');
4 CTX_DDL.SET_ATTRIBUTE('TEST_DETAIL', 'DETAIL_TABLE', 'T1');
5 CTX_DDL.SET_ATTRIBUTE('TEST_DETAIL', 'DETAIL_KEY', 'FID');
6 CTX_DDL.SET_ATTRIBUTE('TEST_DETAIL', 'DETAIL_LINENO', 'SEQ');
7 CTX_DDL.SET_ATTRIBUTE('TEST_DETAIL', 'DETAIL_TEXT', 'DOCS');
8 END;
9 /

PL/SQL procedure successfully completed.

SQL> CREATE INDEX IND_T_DOCS ON T (TITLE) INDEXTYPE IS CTXSYS.CONTEXT
2 PARAMETERS ('DATASTORE TEST_DETAIL');

Index created.

SQL> SELECT * FROM T WHERE CONTAINS(TITLE, 'MASTER') > 0;

ID AUTHER TITLE
---------- ------------------------------ ------------------------------
2 YTK DETAIL DATASTORE DOC


同样,建立这种类型的索引必须要创建一个PREFERENCE,并设置主子表的一些属性。BINARY属性设置在明细记录

后是否添加换行。DETAIL_TABLE属性设置子表名称。DETAIL_KEY属性设置子表的外键列。DETAIL_LINENO设置子

表中文档的顺序。DETAIL_TEXT设置为索引的字段名称。

建立好PERFERENCE,并设置属性后,创建索引就很简单了,需要注意的是,由于真正被索引的列是子表上的列,

因此选择主表中那个列作为索引列并不重要。但是选定之后,以后的查询必须指明这个列。而且,如果子表中被

索引的文档内容发生变化,也必须通过修改索引列来使Oracle认识到被索引数据发生修改。

最后说明一点,由于使用了DETAIL_DATASTORE选项,主表中的被索引列的内容并没有包含在全文索引中。

SQL> SELECT * FROM T WHERE CONTAINS(TITLE, 'DOC') > 0;

no rows selected


各参数的说明如下:
Attribute Attribute Value
binary
Specify TRUE for Oracle to add no newline character after each detail row.

Specify FALSE for Oracle to add a newline character (n) after each detail row automatically.

detail_table
Specify name of detail table (OWNER.TABLE if necessary)

detail_key
Specify name of detail table foreign key column(s)

detail_lineno
Specify name of detail table sequence column.

detail_text
Specify name of detail table text column.

 

 

 

这篇文章继续讨论全文索引的DATASTORE属性,介绍NESTED_DATASTORE。
全文索引支持将数据存储在多个列中或存储在主子表中,全文索引还支持将数据存储在嵌套表中。嵌套表的例子和主子表比较类似:

首先创建嵌套表对象,并建立嵌套表:

SQL> CREATE TYPE T_NESTED_REC AS OBJECT
2 (
3 LINE_NO NUMBER,
4 TEXT VARCHAR2(100)
5 );
6 /

类型已创建。

SQL> CREATE TYPE T_NESTED_TAB AS TABLE OF T_NESTED_REC;
2 /

类型已创建。

SQL> CREATE TABLE T (ID NUMBER PRIMARY KEY, DOCS T_NESTED_TAB, OTHER VARCHAR2(1))
2 NESTED TABLE DOCS STORE AS NESTED_T;

表已创建。

插入数据一般有两种方式,第一种使用直接将数据填入到嵌套表中的方法,当嵌套表包含的记录不多时,采用这种方法给方便。

第二种先初始化行记录,在一次将嵌套表的记录增加到嵌套表中。

SQL> INSERT INTO T VALUES
2 (
3 1,
4 T_NESTED_TAB(T_NESTED_REC(1, 'THIS IS A NESTED TABLE EXAMPLE'),
5 T_NESTED_REC(2, 'THIS IS THE FIRST ROW IN TABLE')),
6 1
7 );

已创建 1 行。

SQL> INSERT INTO T VALUES (2, T_NESTED_TAB(), 1);

已创建 1 行。

SQL> INSERT INTO TABLE(SELECT DOCS FROM T WHERE ID = 2) VALUES (1, 'THIS THE SECOND WAY TO INSERT');

已创建 1 行。

SQL> INSERT INTO TABLE(SELECT DOCS FROM T WHERE ID = 2) VALUES (2, 'A ROW IN THE NESTED TABLE');

已创建 1 行。

SQL> INSERT INTO TABLE(SELECT DOCS FROM T WHERE ID = 2) VALUES (3, 'THIS GRAMMER IS VERY SPECIAL');

已创建 1 行。

SQL> COMMIT;

提交完成。

下面需要在建立一个NESTED_DATASTORE,并设置相应的参数。参数的设置和DETAIL_DATASTORE很类似。

NESTED_COLUMN 设置表中嵌套表列的列名;NESTED_TYPE设置嵌套表使用的对象名称已经对象的用户名;

NESTED_LONENO设置嵌套表中记录的顺序;NESTED_TEXT设置嵌套表中被索引列的名称;BINARY设置是否在嵌套表

记录后增加换行。


SQL> BEGIN
2 CTX_DDL.CREATE_PREFERENCE('TEST_NESTED', 'NESTED_DATASTORE');
3 CTX_DDL.SET_ATTRIBUTE('TEST_NESTED', 'NESTED_COLUMN', 'DOCS');
4 CTX_DDL.SET_ATTRIBUTE('TEST_NESTED', 'NESTED_TYPE', 'myuser.T_NESTED_TAB');
5 CTX_DDL.SET_ATTRIBUTE('TEST_NESTED', 'NESTED_LINENO', 'LINE_NO');
6 CTX_DDL.SET_ATTRIBUTE('TEST_NESTED', 'NESTED_TEXT', 'TEXT');
7 END;
8 /

PL/SQL 过程已成功完成。

在设定NESTED_TYPE时必须指定用户名,否则在建立索引时会出错如下:
DRG-12800: Attribute NESTED_TYPE must have owner name as prefix


最后就可以创建索引了,注意索引创建到OTHER列上,这是由于全文索引不能直接建立在嵌套表的所在列上。


SQL> CREATE INDEX IND_T_OTHER ON T(OTHER) INDEXTYPE IS CTXSYS.CONTEXT
2 PARAMETERS ('DATASTORE TEST_NESTED');

索引已创建。

SQL> SELECT ID FROM T WHERE CONTAINS(OTHER, 'SECOND') > 0;

ID
----------
2

SQL> CREATE INDEX IND_T_DOCS ON T(DOCS) INDEXTYPE IS CTXSYS.CONTEXT
2 PARAMETERS ('DATASTORE TEST_NESTED');
CREATE INDEX IND_T_DOCS ON T(DOCS) INDEXTYPE IS CONTEXT
*
ERROR 位于第 1 行:
ORA-22904: 嵌套表列的参考无效

最后需要说明的还是索引同步的问题,必须通过修改OTHER列来通知Oracle嵌套表的数据已经发生了变化。同样的,查询也必须对OTHER列进行查询。