本文于 2 天前发布,最后更新于 2 天前
全文检索技术是智能信息管理的关键技术之一,其主要目的就是实现对大容量的非结构化数据的快速查找,DM 实现了全文检索功能,并将其作为 DM 服务器的一个较独立的组件,提供更加准确的全文检索功能,较好地解决了模糊查询方式带来的问题。
DM 中,全文索引必须在基表定义,而不能在系统表,视图,临时表,列存表,外部表上定义,同一个列只能创建一个全文索引,在创建全文索引的时候,用户可以为分词器定义分词参数,即控制分词器的数量。
全文检索的中文分词依赖系统词库,该词库是只读的,不允许修改。
- CHINESE_LEXER——中文最少分词
- CHINESE_VGRAM_LEXER——机械双字分词
- CHINESE_FP_LEXER——中文最多分词
- ENGLISH_LEXER——英文分词
- DEFAULT_LEXER——默认分词,中文最少分词
创建全文索引后,系统会自动产生如下辅助表
- I 表:CTI$INDEX_NAME$I 用来保存分词结果
- P 表:CTI$INDEX_NAME$P 用来保存基表发生的增量数据变化
- N 表:CTI$INDEX_NAME$N 用来保存原表记录ROWID 和新记录条记录 DOCID 的映射关系
- D 表:CTI$INDEX_NAME$D 保存了所有的将被删除的DOCID
创建全文索引
CREATE CONTEXT INDEX CTI_PERSON_ADDRESS1 ON PERSON.ADDRESS(ADDRESS1) LEXER DEFAULT_LEXER;
全文索引的基本信息会保存到CTISYS模式下的系统表SYSCONTEXTINDEXES中

查询分词
--查询前需要在全文索引处右键-完全填充
SELECT WORD FROM PERSON.CTI$CTI_PERSON_ADDRESS1$I;
重建全文索引
ALTER CONTEXT INDEX CTI_PERSON_ADDRESS1 ON PERSON.ADDRESS REBUILD;
利用全文索引搜索
SELECT * FROM PERSON.ADDRESS WHERE CONTAINS(ADDRESS1,'洪山区' AND '春晓' AND '202');
普通模糊查询
SELECT * FROM PERSON.ADDRESS WHERE ADDRESS1 LIKE '%洪山区%' AND ADDRESS1 LIKE '%春晓%' AND ADDRESS1 LIKE '%202%';
用全文索引+条件
SELECT * FROM PERSON.ADDRESS WHERE CONTAINS(ADDRESS1,'洪山区' AND '春晓' AND '202') AND CITY='武汉市洪山区';
更新增加全文索引
ALTER CONTEXT INDEX CTI_PERSON_ADDRESS1 ON PERSON.ADDRESS INCREMENT;
删除全文索引
DROP CONTEXT INDEX CTI_PERSON_ADDRESS1 ON PERSON.ADDRESS;
查看全文索引
SELECT * FROM CTISYS.SYSCONTEXTINDEXES;
自定义函数查看分词
--获取分词的函数
CREATE OR REPLACE FUNCTION F_GET_CTI_TOKEN(V_INPUT VARCHAR2)
RETURN VARCHAR2
IS
PRAGMA AUTONOMOUS_TRANSACTION;
V_TMP_TABNAME VARCHAR2(128);
V_RET VARCHAR2(32767);
BEGIN
V_TMP_TABNAME := 'T_'||SYS_GUID;
EXECUTE IMMEDIATE 'CREATE TABLE '||V_TMP_TABNAME||'(VAL VARCHAR2(4000))';
EXECUTE IMMEDIATE 'INSERT INTO '||V_TMP_TABNAME||' VALUES(?)' USING V_INPUT;
EXECUTE IMMEDIATE 'COMMIT';
EXECUTE IMMEDIATE 'CREATE CONTEXT INDEX CTI_'||V_TMP_TABNAME||' ON '||V_TMP_TABNAME||' (VAL) LEXER CHINESE_LEXER SYNC ';
EXECUTE IMMEDIATE 'SELECT LISTAGG(WORD,'','') WITHIN GROUP (ORDER BY ROWID) FROM CTI$CTI_'||V_TMP_TABNAME||'$I' INTO V_RET;
EXECUTE IMMEDIATE 'DROP TABLE '||V_TMP_TABNAME||' CASCADE PURGE ';
RETURN V_RET;
END;
--测试
SELECT F_GET_CTI_TOKEN('我这里测试一下看看效果如何,如果效果不好,要再次换一个办法来测试才行');
--返回
我,这里,测试,一下,看看,效果,如何,如果,不好,要,行,再次,换,一个,办法,来,才
SELECT F_GET_CTI_TOKEN('北京市东城区东长安街33号');
--返回
东,33,号,北京市,东城区,长安街