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)用户授权角色。为该用户授权 RESOURCECONNECTCTXAPP 角色:

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> 

参考资料

原文地址:https://www.cnblogs.com/liuning8023/p/2652720.html