SQLite FTS5虚拟表:将连字符视为令牌一部分的正确语法
在SQLite 3.47.1的FTS5中保留连字符为令牌一部分的正确方案
要让FTS5将连字符(-)视为令牌的一部分,避免像24-34这样的字符串被拆分为两个独立令牌,核心是配置FTS5的分词器,指定连字符属于令牌字符而非分隔符。以下是正确的实现步骤:
正确的CREATE TABLE语法
使用FTS5默认的unicode61分词器,通过tokenchars参数将连字符加入令牌字符列表:
CREATE VIRTUAL TABLE addresses USING fts5( street, tokenize='unicode61 tokenchars="-"' );
语法说明
unicode61是FTS5的默认分词器,支持Unicode字符处理;tokenchars="-"明确告诉分词器:连字符应被当作令牌的一部分,而非用于拆分字符串的分隔符。这样24-34会被索引为单个完整令牌,不会被拆分为24和34。
在R中执行的注意事项
在R中运行SQL语句时,需要注意字符串的转义问题,避免引号冲突。两种可行的写法:
- 转义双引号:
library(RSQLite) conn <- dbConnect(SQLite()) dbExecute(conn, "CREATE VIRTUAL TABLE addresses USING fts5( street, tokenize='unicode61 tokenchars=\"-\"' )")
- 使用单引号嵌套:
dbExecute(conn, 'CREATE VIRTUAL TABLE addresses USING fts5( street, tokenize="unicode61 tokenchars=\'-'" )')
验证效果
插入测试数据并查询,确认行为符合预期:
-- 插入数据 INSERT INTO addresses(street) VALUES ('24-34 Main St'), ('34 Oak Ave'); -- 搜索"34",仅返回匹配独立令牌的结果 SELECT * FROM addresses WHERE addresses MATCH '34';
执行后只会返回34 Oak Ave,不会命中24-34 Main St,说明连字符已被正确保留为令牌的一部分。
替代方案(复杂场景)
如果需要更自定义的分词规则,可以编写FTS5自定义分词器,但这需要C语言扩展,仅推荐在unicode61配置无法满足需求时使用。对于你的场景,上述tokenchars配置完全足够。
内容的提问来源于stack exchange,提问作者AussieAndy
相关产品推荐
相关产品推荐

