Oracle 19c Text建索引遇单词截断为64字符但令牌限64字节报错
Oracle 19c Text 全文索引超长多字节令牌报错解决方案
该报错的核心原因是Oracle Text的全文索引令牌存储列DR$TOKEN为硬编码的VARCHAR2(64 BYTE),默认词法分析器仅按字符数截断到64位,当包含占2字节的葡萄牙语变音字符时,总字节数超出64字节上限就会触发报错。你修改NLS_LENGTH_SEMANTICS不生效是因为该参数不会修改Oracle内部自动创建的索引表的列定义,可选择以下方案解决:
方案1:调整词法分析器最大令牌长度(推荐)
调整BASIC_LEXER的MAX_TOKEN_LENGTH参数,按单字符最大2字节的标准将上限设为32,保证所有令牌字节数不超过64字节,修改后的创建语句示例如下:begin ctx_ddl.create_index_set('ix_iset'); ctx_ddl.create_preference('ix_pref', 'BASIC_LEXER'); ctx_ddl.set_attribute('ix_pref', 'skipjoins', '-'); ctx_ddl.set_attribute ( 'ix_pref', 'index_stems', 'portuguese'); ctx_ddl.set_attribute ( 'ix_pref', 'index_text', 'YES'); ctx_ddl.set_attribute ( 'ix_pref', 'base_letter', 'YES'); -- 新增配置:限制最大令牌长度为32字符 ctx_ddl.set_attribute ( 'ix_pref', 'max_token_length', '32'); end; / CREATE INDEX ix_tx_column ON MYTABLE(tx_column) INDEXTYPE IS CTXSYS.CTXCAT PARAMETERS ('index set ix_iset lexer ix_pref');如果你的业务场景中单字节字符占比更高,也可以根据实际情况适当调高该参数到40~48,只要保证令牌总字节数不超过64即可。
方案2:配置自动跳过超长令牌
如果超长单词本身没有业务检索价值,可以配置词法分析器自动跳过超出长度限制的令牌,避免报错,只需在创建词法偏好的逻辑中新增如下配置即可:ctx_ddl.set_attribute ( 'ix_pref', 'overflow_token', 'SKIP');该方案的代价是超出长度的单词不会被索引,也无法通过全文检索匹配到。
方案3:预处理文本后建索引
如果需要保留超长单词的检索能力,可新增一个虚拟生成列,自定义逻辑将原字段中的单词按字节数截断到64字节以内,再在生成列上创建全文索引:-- 新增预处理虚拟列,自定义实现按字节截断超长单词的逻辑 ALTER TABLE MYTABLE ADD tx_column_clean VARCHAR2(4000) GENERATED ALWAYS AS (自定义截断逻辑) VIRTUAL; -- 在预处理后的列上建索引 CREATE INDEX ix_tx_column_clean ON MYTABLE(tx_column_clean) INDEXTYPE IS CTXSYS.CTXCAT PARAMETERS ('index set ix_iset lexer ix_pref');检索时对应使用预处理后的字段做匹配即可。
内容的提问来源于stack exchange,提问作者curyfernando
相关产品推荐
相关产品推荐

