Oracle 11g Release 1 (11.1) Oracle Text 如何创建 CTXCAT 索引
本文内容
- 创建一个 Oracle 全文检索用户
- 创建表和插入数据
- 创建 CTXCAT 索引
- 针对中文创建 CTXCAT 索引
使用 Oracle 全文检索 CTXCAT 索引能够获得更好地混合查询的性能。通常,你可以利用该索引为小文本或文本片段建立索引。例如,表的列,如条目名称、价格和描述,可以包含在索引中,以提高混合查询性能。
该索引在 DML 后是事务性、自动更新的,因此无需 CTX_DDL.SYNC_INDEX。
创建一个 Oracle 全文检索用户并授权
在使用 Oracle 全文检索 CTXCAT 索引和 CTX PL/SQL 包之前,创建一个具有 CTXAPP 角色的用户。该角色使你可以做如下事情:
- 创建和删除 Oracle 全文检索的索引引用(preference)。该引用可以认为是你所创建索引的“偏好”,毕竟索引是有侧重点的。
- 使用 Oracle 全文检索 CTX PL/SQL 包
以 DBA 身份登录,创建用户并授权,如下所述:
1)创建用户 MYUSER / myuser_password:
CREATE USER myuser IDENTIFIED BY myuser_password;
2)用户授权角色。为该用户授权 RESOURCE、CONNECT 和 CTXAPP 角色:
GRANT RESOURCE, CONNECT, CTXAPP TO MYUSER;
3)授权执行 CTX PL/SQL 包的权限
Oracle 全文检索有很多包,可以让你完成从同步全文检索索引,到高亮显示文本的所有动作。例如,CTX_DDL 包含了 SYNC_INDEX 过程,该存储过程可以同步全文检索的索引。
若想调用这些过程,你的应用程序需要有执行这些包的权限。例如,为 MYUSER 用户授权执行所有 Oracle 全文的包的权限,如下代码:
GRANT EXECUTE ON CTXSYS.CTX_CLS TO myuser;
GRANT EXECUTE ON CTXSYS.CTX_DDL TO myuser;
GRANT EXECUTE ON CTXSYS.CTX_DOC TO myuser;
GRANT EXECUTE ON CTXSYS.CTX_OUTPUT TO myuser;
GRANT EXECUTE ON CTXSYS.CTX_QUERY TO myuser;
GRANT EXECUTE ON CTXSYS.CTX_REPORT TO myuser;
GRANT EXECUTE ON CTXSYS.CTX_THES TO myuser;
GRANT EXECUTE ON CTXSYS.CTX_ULEXER TO myuser;
创建表并插入数据
本节演示为一个拍卖站点创建目录索引。该站点销售如摄像机和 CD 播放器等电子设备。新的条目每天都会增加,包括条目描述(名称)、类别、拍卖日期和拍卖价格。
应用程序查询若想获得良好的响应时间,重要的是确定用户频繁检索哪个列,以创建合适的 CTXCAT 索引。查询该索引需要 CATSEARCH 操作符。
1)用上面创建的 myuser 用户连接数据库
SQL> CONNECT myuser;
2)创建 auction 表,并向该表插入 4 条数据
SQL> CREATE TABLE auction(
2 item_id NUMBER,
3 title VARCHAR2(100),
4 category_id NUMBER,
5 price NUMBER,
6 bid_close DATE);
Table created
SQL> INSERT INTO AUCTION
2 VALUES
3 (1, 'NIKON CAMERA', 1, 400, to_date('2012-8-1', 'yyyy-mm-dd'));
1 row inserted
SQL> INSERT INTO AUCTION
2 VALUES
3 (2, 'OLYMPUS CAMERA', 1, 300, to_date('2012-8-5', 'yyyy-mm-dd'));
1 row inserted
SQL> INSERT INTO AUCTION
2 VALUES
3 (3, 'PENTAX CAMERA', 1, 200, to_date('2012-8-10', 'yyyy-mm-dd'));
1 row inserted
SQL> INSERT INTO AUCTION
2 VALUES
3 (4, 'CANON CAMERA', 1, 250, to_date('2012-8-20', 'yyyy-mm-dd'));
1 row inserted
SQL>
创建 CTXCAT 索引
1)确定可能检索的标准是什么。假设本节所有的查询使用 title 列,并按 price 排序。在 CATSEARCH 操作符中,检索 title 列的指定值。
2)为了使 Oracle 全文检索更有效地执行查询,需要一个 price 列子索引。这样,查询将按 price 列排序。如下所示,创建一个名为 "auction_iset" 索引集,并添加 price 列作为其子索引。
SQL> EXEC CTX_DDL.create_index_set('auction_iset')
PL/SQL procedure successfully completed
SQL> EXEC CTX_DDL.add_index('auction_iset','price')
PL/SQL procedure successfully completed
SQL>
3)利用 "auction_iset" 索引集在 auction 表的 title 列上创建 CTXCAT 索引。
SQL> CREATE INDEX auction_titlex ON AUCTION(title) INDEXTYPE IS CTXSYS.CTXCAT PARAMETERS ('index set auction_iset');
Index created
SQL>
图 1 拍卖表的模式(表结构)和 CTXCAT 索引
4)用 CATSEARCH 操作符查询 CTXCAT 索引。
SQL> SELECT title, price
2 FROM auction;
TITLE PRICE
-------------------- ----------
NIKON CAMERA 400
OLYMPUS CAMERA 300
PENTAX CAMERA 200
CANON CAMERA 250
SQL>
SQL> SELECT title, price
2 FROM auction
3 WHERE CATSEARCH(title, 'CAMERA', 'order by price') > 0;
TITLE PRICE
-------------------- ----------
PENTAX CAMERA 200
CANON CAMERA 250
OLYMPUS CAMERA 300
NIKON CAMERA 400
SQL>
5)插入新数据后,再查询。
SQL> INSERT INTO AUCTION
2 VALUES
3 (5, 'FUJI CAMERA', 1, 350, to_date('2012-9-10', 'yyyy-mm-dd'));
1 row inserted
SQL> INSERT INTO AUCTION
2 VALUES
3 (6, 'SONY CAMERA', 1, 310, to_date('2012-9-22', 'yyyy-mm-dd'));
1 row inserted
SQL> SELECT title, price
2 FROM auction
3 WHERE CATSEARCH(title, 'CAMERA', 'order by price') > 0;
TITLE PRICE
-------------------- ----------
PENTAX CAMERA 200
CANON CAMERA 250
OLYMPUS CAMERA 300
SONY CAMERA 310
FUJI CAMERA 350
NIKON CAMERA 400
6 rows selected
SQL>
针对中文创建 CTXCAT 索引
上面演示 auction 表的数据是英文的,可如果是中文,再这样创建 CTXCAT 索引就显示不合时宜。下面演示针对中文的 CTXCAT 索引。
创建 auction_ch 表
SQL> create table AUCTION_CH
2 (
3 ITEM_ID NUMBER,
4 TITLE VARCHAR2(100),
5 CATEGORY_ID NUMBER,
6 PRICE NUMBER,
7 BID_CLOSE DATE
8 );
Table created
SQL>
插入中文的测试数据
SQL> INSERT INTO AUCTION_CH
2 VALUES
3 (1, '尼康相机', 1, 400, to_date('2012-8-1', 'yyyy-mm-dd'));
1 row inserted
SQL> INSERT INTO AUCTION_CH
2 VALUES
3 (2, '奥林巴斯相机', 1, 300, to_date('2012-8-5', 'yyyy-mm-dd'));
1 row inserted
SQL> INSERT INTO AUCTION_CH
2 VALUES
3 (3, '宾得相机', 1, 200, to_date('2012-8-10', 'yyyy-mm-dd'));
1 row inserted
SQL> INSERT INTO AUCTION_CH
2 VALUES
3 (4, '佳能相机', 1, 250, to_date('2012-8-20', 'yyyy-mm-dd'));
1 row inserted
SQL>
创建中文分词和 workdlist
SQL> EXEC CTX_DDL.create_preference('chinese_lexer','chinese_vgram_lexer')
PL/SQL procedure successfully completed
SQL> EXEC CTX_DDL.create_preference('mywordlist', 'BASIC_WORDLIST')
PL/SQL procedure successfully completed
SQL> EXEC CTX_DDL.set_attribute('mywordlist','PREFIX_INDEX','TRUE')
PL/SQL procedure successfully completed
SQL> EXEC CTX_DDL.set_attribute('mywordlist','SUBSTRING_INDEX', 'YES')
PL/SQL procedure successfully completed
SQL>
创建 CTXCAT 索引
SQL> create index auction_ch_idx on auction_ch(title) indextype is ctxsys.ctxcat parameters('lexer chinese_lexer wordlist mywordlist');
Index created
SQL>
利用 catsearch 操作符查询 CTXCAT 索引
SQL> select * from auction_ch;
ITEM_ID TITLE CATEGORY_ID PRICE BID_CLOSE
---------- --------------- ----------- ---------- -----------
1 尼康相机 1 400 2012/8/1
2 奥林巴斯相机 1 300 2012/8/5
3 宾得相机 1 200 2012/8/10
4 佳能相机 1 250 2012/8/20
SQL> select * from auction_ch where catsearch(title, '相', null) > 0;
ITEM_ID TITLE CATEGORY_ID PRICE BID_CLOSE
---------- --------------- ----------- ---------- -----------
SQL> select * from auction_ch where catsearch(title, '机', null) > 0;
ITEM_ID TITLE CATEGORY_ID PRICE BID_CLOSE
---------- --------------- ----------- ---------- -----------
1 尼康相机 1 400 2012/8/1
2 奥林巴斯相机 1 300 2012/8/5
3 宾得相机 1 200 2012/8/10
4 佳能相机 1 250 2012/8/20
SQL> select * from auction_ch where catsearch(title, '得', null) > 0;
ITEM_ID TITLE CATEGORY_ID PRICE BID_CLOSE
---------- --------------- ----------- ---------- -----------
SQL> select * from auction_ch where catsearch(title, '相机', null) > 0;
ITEM_ID TITLE CATEGORY_ID PRICE BID_CLOSE
---------- --------------- ----------- ---------- -----------
1 尼康相机 1 400 2012/8/1
2 奥林巴斯相机 1 300 2012/8/5
3 宾得相机 1 200 2012/8/10
4 佳能相机 1 250 2012/8/20
SQL> select * from auction_ch where catsearch(title, '尼康', null) > 0;
ITEM_ID TITLE CATEGORY_ID PRICE BID_CLOSE
---------- --------------- ----------- ---------- -----------
1 尼康相机 1 400 2012/8/1
SQL>