Oracle 全文检索(Oracle Text)
Oracle 全文检索(Oracle Text)
适用版本:Oracle Database 9i / 10g / 11g / 12c / 19c / 23ai 文档版本:v1.0 / 2026-07
1. 概述
Oracle Text 提供全文检索能力[1]:
特点:
- 全文搜索
- 模糊匹配
- 多语言
- 文档检索
2. 索引类型
| 类型 | 说明 |
|---|---|
| CONTEXT | 文本列(CLOB/VARCHAR2) |
| CTXCAT | 目录项搜索 |
| CTXRULE | 查询规则 |
| CTXXPATH | XML 搜索 |
3. CONTEXT 索引
3.1 创建
CREATE INDEX idx_emp_resume ON employees(resume)
INDEXTYPE IS CTXSYS.CONTEXT;
3.2 查询
-- CONTAINS
SELECT * FROM employees
WHERE CONTAINS(resume, 'Oracle') > 0;
-- 多词
SELECT * FROM employees
WHERE CONTAINS(resume, 'Oracle AND Java') > 0;
-- 或
SELECT * FROM employees
WHERE CONTAINS(resume, 'Oracle OR MySQL') > 0;
-- 模糊
SELECT * FROM employees
WHERE CONTAINS(resume, 'fuzzy(Oracle)') > 0;
-- 通配符
SELECT * FROM employees
WHERE CONTAINS(resume, 'Ora%') > 0;
3.3 查询分数
SELECT
employee_id,
SCORE(1) AS score
FROM employees
WHERE CONTAINS(resume, 'Oracle', 1) > 0
ORDER BY score DESC;
4. 操作符
4.1 逻辑
OR / |
AND / &
NOT / -
4.2 NEAR
-- 相邻
WHERE CONTAINS(resume, 'Oracle NEAR Java') > 0;
4.3 短语
-- 精确短语
WHERE CONTAINS(resume, '"Oracle Database"') > 0;
4.4 模糊
-- fuzzy
WHERE CONTAINS(resume, 'fuzzy(Oracle)') > 0;
-- soundex(发音相似)
WHERE CONTAINS(resume, '!Smith') > 0;
-- stem(词干)
WHERE CONTAINS(resume, '$run') > 0;
-- running, runs 等
5. 索引同步
5.1 自动同步
-- ON COMMIT
CREATE INDEX idx_emp_resume ON employees(resume)
INDEXTYPE IS CTXSYS.CONTEXT
PARAMETERS ('SYNC (ON COMMIT)');
-- 定时
CREATE INDEX idx_emp_resume ON employees(resume)
INDEXTYPE IS CTXSYS.CONTEXT
PARAMETERS ('SYNC (EVERY "SYSDATE+1/24")');
5.2 手动同步
EXEC CTX_DDL.SYNC_INDEX('idx_emp_resume');
5.3 优化
-- 重建
ALTER INDEX idx_emp_resume REBUILD;
-- 优化
EXEC CTX_DDL.OPTIMIZE_INDEX('idx_emp_resume', 'FULL');
6. CTXCAT 索引
6.1 创建
BEGIN
CTX_DDL.CREATE_INDEX_SET('emp_iset');
CTX_DDL.ADD_INDEX('emp_iset', 'dept_id');
END;
/
CREATE INDEX idx_emp_cat ON employees(resume)
INDEXTYPE IS CTXSYS.CTXCAT
PARAMETERS ('INDEX SET emp_iset');
6.2 查询
SELECT * FROM employees
WHERE CATSEARCH(resume, 'Oracle', 'dept_id = 10') > 0;
7. 多列索引
-- 多列索引
CREATE INDEX idx_emp_multi ON employees(resume, job_desc)
INDEXTYPE IS CTXSYS.CONTEXT
FILTER BY dept_id;
8. 词法分析
8.1 中文分词
BEGIN
CTX_DDL.CREATE_PREFERENCE('my_lexer', 'CHINESE_LEXER');
END;
/
CREATE INDEX idx_emp_resume ON employees(resume)
INDEXTYPE IS CTXSYS.CONTEXT
PARAMETERS ('LEXER my_lexer');
8.2 自定义词库
BEGIN
CTX_DDL.CREATE_STOPLIST('my_stop');
CTX_DDL.ADD_STOPWORD('my_stop', 'the');
CTX_DDL.ADD_STOPWORD('my_stop', 'a');
END;
/
CREATE INDEX idx_emp_resume ON employees(resume)
INDEXTYPE IS CTXSYS.CONTEXT
PARAMETERS ('STOPLIST my_stop');
9. 文档检索
9.1 二进制文档
-- BLOB 存储文档
CREATE TABLE docs (
id NUMBER,
content BLOB
);
-- 自动过滤
CREATE INDEX idx_docs ON docs(content)
INDEXTYPE IS CTXSYS.CONTEXT
PARAMETERS ('FILTER CTXSYS.AUTO_FILTER');
9.2 查询
SELECT id FROM docs WHERE CONTAINS(content, 'Oracle') > 0;
10. 应用场景
10.1 简历搜索
CREATE INDEX idx_resume ON candidates(resume)
INDEXTYPE IS CTXSYS.CONTEXT;
SELECT * FROM candidates
WHERE CONTAINS(resume, 'Java AND Spring') > 0
ORDER BY SCORE(1) DESC;
10.2 商品搜索
CREATE INDEX idx_product ON products(description)
INDEXTYPE IS CTXSYS.CONTEXT;
SELECT * FROM products
WHERE CONTAINS(description, '手机') > 0;
10.3 文档管理
-- PDF/Word 检索
CREATE INDEX idx_doc ON documents(content)
INDEXTYPE IS CTXSYS.CONTEXT
PARAMETERS ('FILTER CTXSYS.AUTO_FILTER');
SELECT * FROM documents
WHERE CONTAINS(content, '合同') > 0;
11. 常见坑与排错
11.1 ORA-29871: 索引未同步
-- 同步索引
EXEC CTX_DDL.SYNC_INDEX('idx_name');
11.2 查询无结果
-- 1. 索引未同步
-- 2. 词法分析问题
-- 3. 大小写
-- 4. 停用词
11.3 性能差
-- 1. 优化索引
EXEC CTX_DDL.OPTIMIZE_INDEX('idx_name', 'FULL');
-- 2. 限制结果
-- 3. 加 SCORE 排序
11.4 中文分词
-- 使用 CHINESE_LEXER
-- 或 CHINESE_VGRAM_LEXER
12. 最佳实践
- CONTEXT 索引:文本列
- CTXCAT 索引:目录搜索
- 自动同步:ON COMMIT
- 定期优化:性能
- 中文用 CHINESE_LEXER:分词
- SCORE 排序:相关性
- 停用词表:减少索引
- 多列索引:综合搜索
- AUTO_FILTER:文档检索
- 监控索引:状态
13. 参考资料
[1] Oracle Text Reference 19c https://docs.oracle.com/en/database/oracle/oracle-database/19/ccref/