Oracle Text是Oracle数据库内建的全文检索组件,它通过CONTEXT索引对文本字段建立倒排索引。分词器(Lexer)决定文本如何被切分成词元(Token),词典与停用词表则进一步影响索引的粒度和查询行为。对于英文文本,默认的BASIC_LEXER按照空格、标点和大小写规则切分即可获得较好效果;但当中文内容进入全文索引时,BASIC_LEXER无法识别词语边界,往往把整句连续汉字当作一个Token,导致CONTAINS查询无法命中预期结果。因此,理解并正确配置Oracle Text的词典与分词器,是构建中文全文检索能力的关键一步。

一、Oracle Text分词器的工作机制与常见类型
Oracle Text在创建CONTEXT索引时,会根据指定的词法分析器(Lexer)对文本进行预处理。预处理流程通常包括字符过滤、大小写转换、停用词过滤和Token切分。Token是全文检索的最小匹配单位,查询词也会经过同样的分词管道。如果索引建立时分词结果与查询时分词结果不一致,CONTAINS就无法正确匹配。这意味着分词器选择必须在建索引之前确定,后续修改往往需要重建索引。
Oracle Text提供了多种内置分词器。BASIC_LEXER适合英语、法语等以空格分词的语言,支持扩展字符集和复合词处理;CHINESE_VGRAM_LEXER是一种基于二元切分的分词器,它把相邻两个汉字作为一个Token,例如“全文检索”会被切成“全文”“文检”“检索”。这种方式的优点是无需外部词典,召回率较高,几乎不会漏掉词,但会产生大量无意义Token,增加索引体积,查询时也可能返回较多噪声。CHINESE_LEXER则是基于词典的中文分词器,会按照内置或自定义词典识别完整词语,切分结果更接近自然语义,准确率较高,但对未登录词的识别能力有限。MULTI_LEXER用于多语言混合场景,可以为不同语言指定不同的子分词器;WORLD_LEXER则能根据Unicode范围自动选择语言分词器。
除了分词器本身,Oracle Text还允许为分词器配置属性。例如MIXED_CASE可以控制是否保留大小写差异,TIMEOUT限制长文本处理时间。词典和停用词表也属于词法分析相关的配置对象。停用词表(Stoplist)中的词不会进入索引,通常将“的”“了”“是”等高频虚词加入停用词表,可以减小索引尺寸并提升查询性能。理解这些对象之间的关系,是后续配置工作的基础。
二、配置中文分词器与自定义词典
要为中文列创建全文索引,最直接的方法是使用CHINESE_VGRAM_LEXER。它不依赖外部词典,适合快速搭建原型或处理包含大量专有名词、产品型号的文本。下面的代码创建一个基于CHINESE_VGRAM_LEXER的偏好,并添加一个简单的停用词表。
BEGIN
-- 创建中文二元切分分词器偏好
ctx_ddl.create_preference('my_chinese_vgram', 'CHINESE_VGRAM_LEXER');
ctx_ddl.set_attribute('my_chinese_vgram', 'MIXED_CASE', 'YES');
-- 创建停用词表
ctx_ddl.create_preference('my_stoplist', 'BASIC_STOPLIST');
ctx_ddl.add_stopword('my_stoplist', '的');
ctx_ddl.add_stopword('my_stoplist', '了');
ctx_ddl.add_stopword('my_stoplist', '是');
END;
/
当数据表中同时包含中文和英文内容时,可以配置MULTI_LEXER并分别为不同语言挂载子分词器。下面的示例将英文文本交给BASIC_LEXER处理,中文文本交给CHINESE_VGRAM_LEXER处理。MULTI_LEXER会根据文本的语言特征自动选择子分词器,这对于多语言应用场景非常实用。
BEGIN
-- 英文分词器
ctx_ddl.create_preference('en_lexer', 'BASIC_LEXER');
ctx_ddl.set_attribute('en_lexer', 'BASE_LETTER', 'YES');
-- 中文二元分词器
ctx_ddl.create_preference('zh_lexer', 'CHINESE_VGRAM_LEXER');
-- 多语言组合分词器
ctx_ddl.create_preference('multi_lexer', 'MULTI_LEXER');
ctx_ddl.add_sub_lexer('multi_lexer', 'DEFAULT', 'zh_lexer');
-- 为英文语言代码指定英文分词器
ctx_ddl.add_sub_lexer('multi_lexer', 'ENGLISH', 'en_lexer');
-- 停用词表同样可以复用
ctx_ddl.create_preference('multi_stop', 'BASIC_STOPLIST');
ctx_ddl.add_stopword('multi_stop', 'the');
ctx_ddl.add_stopword('multi_stop', '的');
END;
/
关于自定义词典,如果业务要求中文分词结果更符合行业语义,应当选择CHINESE_LEXER。该分词器基于词典工作,Oracle Text允许数据库管理员将领域术语表维护在数据库表中,并通过Oracle Text提供的词典管理接口让分析器识别这些专有词。虽然配置过程比CHINESE_VGRAM_LEXER复杂,但能显著降低无关Token数量。例如“自然语言处理”在词典分词器下可以作为一个完整Token,而在二元切分下会变成“自然”“然语”“语言”“言处”“处理”五个Token。对于查询准确率要求较高的场景,建议使用CHINESE_LEXER并配合自定义词典。需要注意的是,自定义词典需要定期更新,以保证新词能够被正确切分。
实际创建索引时,通过PARAMETERS子句指定分词器和停用词表偏好即可,例如:
CREATE INDEX doc_text_idx ON documents(text_column)
INDEXTYPE IS CTXSYS.CONTEXT
PARAMETERS('LEXER multi_lexer STOPLIST multi_stop');
索引创建完成后,Oracle Text会在后台生成一系列DR$开头的内部表,其中DR$doc_text_idx$I表记录了每个Token的元数据。可以通过查询该表来验证分词结果,判断词典与分词器是否按预期工作。
三、分词效果验证与常见配置误区
验证分词效果最直观的方法是查询DR$索引Token表。例如创建索引后执行以下SQL查看Token列表:
SELECT token_text, token_count FROM dr$doc_text_idx$i WHERE token_text IS NOT NULL ORDER BY token_count DESC;
如果使用CHINESE_VGRAM_LEXER,token_text列会出现大量双字片段;如果使用CHINESE_LEXER,则会出现完整词语。根据token_count可以评估哪些词被频繁索引,进而调整停用词表或词典。如果发现某个业务核心词被错误切分,应检查词典配置或考虑切换到另一种分词器。同时还可以利用CONTAINS查询的EXPLAIN PLAN功能查看查询解析后的Token序列,进一步确认查询侧分词是否与索引侧一致。
使用全文索引后,数据更新不会自动反映到索引中。必须手动执行同步操作,或者创建一个定期运行的JOB来调用CTX_DDL.SYNC_INDEX。同步频率可以根据数据变更量决定,例如每5分钟同步一次。索引长期不优化会产生碎片,影响查询性能,此时可以调用CTX_DDL.OPTIMIZE_INDEX进行整理。常见的调优方式包括FULL优化、FAST优化和TOKEN优化,具体选择取决于索引碎片程度和对在线业务的影响。
常见配置误区之一是忽略停用词对查询的影响。CONTAINS查询中的停用词会被直接忽略,如果用户搜索“的”等常见字,可能返回空结果。另一个误区是在多语言环境中仍然只使用单一分词器,导致非中文内容被错误切分。还有开发者认为中文分词器自带词典就能识别所有领域术语,实际上专业词汇通常需要自定义词典补充。最后,索引与表数据不同步是很多全文检索失效的直接原因,排查时应优先检查SYNC_INDEX的执行情况。避免这些误区,可以让Oracle Text的词典与分词器配置发挥出最大价值。
Oracle Text的词典与分词器配置并非一次性工作,而是需要根据数据特征和查询日志持续调整。通过合理选择分词器、维护停用词表、补充自定义词典,并配合索引同步与优化,能够在Oracle数据库中构建出高效、稳定的全文检索能力。
Oracle Text中文分词器全文检索修改时间:2026-08-29 21:56:14