全文搜索与文本分析实战指南


快速选型

函数用途适用场景是否需要索引
tokenize
tokenize
文本分词词频统计、标签提取、文本预处理
match_any
match_any
任意词匹配(OR 逻辑)宽泛搜索、关键词过滤是(倒排索引)
match_phrase
match_phrase
精确短语匹配精确查找固定搭配、报错信息是(倒排索引)
match_phrase_prefix
match_phrase_prefix
前缀短语匹配搜索建议、自动补全是(倒排索引)
match_regexp
match_regexp
正则表达式匹配复杂模式提取、日志格式解析

前置准备

本文所有示例基于以下测试数据:

-- 系统日志与文档表 CREATE TABLE search_docs ( id BIGINT, title VARCHAR(500), content VARCHAR(1000), log_level VARCHAR(20), log_message VARCHAR(500) ); INSERT INTO search_docs VALUES (1, '云器 Lakehouse 介绍', '云器 Lakehouse 是一个现代化的数据平台,支持实时分析和 AI 应用。', 'INFO', 'System started successfully.'), (2, '数据管道开发', '使用 Dynamic Table 构建实时数据管道,实现 ODS 到 ADS 的数据流转。', 'ERROR', 'Connection timeout to database.'), (3, '用户行为分析', '通过 BITMAP 函数实现高效的用户重叠分析和精准营销。', 'WARN', 'High memory usage detected.'), (4, 'SQL 函数参考', '本文档介绍了云器 Lakehouse 支持的各类 SQL 函数,包括聚合、窗口、标量等。', 'DEBUG', 'Query execution plan generated.'), (5, '向量检索应用', '利用向量相似度搜索实现语义匹配和推荐系统。', 'INFO', 'Vector index rebuilt.'), (6, '数据安全与合规', '支持行列级权限控制、动态脱敏和审计日志功能。', 'ERROR', 'Authentication failed for user admin.'), (7, '性能优化最佳实践', '通过小文件合并、结果缓存和查询改写提升性能。', 'WARN', 'Disk space running low.'), (8, '多表实时同步', '基于 CDC 技术实现 MySQL 到 Lakehouse 的实时数据同步。', 'INFO', 'CDC stream processing started.'), (9, '外部数据联邦查询', '通过 External Catalog 直接查询 Hive、Iceberg 等外部数据源。', 'DEBUG', 'External catalog metadata refreshed.'), (10, 'AI 模型集成', '在 SQL 中直接调用大语言模型进行文本生成和情感分析。', 'INFO', 'AI model endpoint connected.');


场景 1:文本分词与词频统计(tokenize)

问题

对中文/英文混合文本进行分词,统计高频词汇。

SQL 实现

-- 使用中文分析器分词 SELECT id, title, tokenize(content, map('analyzer', 'chinese')) AS tokens FROM search_docs WHERE id IN (1, 2, 3);

输出:

idtitletokens
1云器 Lakehouse 介绍云器:lakehouse:是:一个:现代化:的:数据:平台:支持:实时:分析:和:ai:应用
2数据管道开发使用:dynamic:table:构建:实时:数据:管道:实现:ods:到:ads:的:数据:流转
3用户行为分析通过:bitmap:函数:实现:高效:的:用户:重叠:分析:和:精准:营销

词频统计实战

-- 展开分词结果并统计 Top 10 高频词 SELECT token, COUNT(*) AS freq FROM ( SELECT tokenize(content, map('analyzer', 'chinese')) AS token_array FROM search_docs ), LATERAL VIEW explode(token_array) t AS token WHERE LENGTH(token) > 1 -- 过滤单字 GROUP BY token ORDER BY freq DESC LIMIT 10;

输出:

tokenfreq
数据4
实现3
分析2
支持2
实时2
......

场景 2:正则表达式匹配(match_regexp)

问题

从日志消息中提取特定格式的错误码或 IP 地址。

SQL 实现

-- 匹配包含 "timeout" 或 "failed" 的日志 SELECT id, log_level, log_message FROM search_docs WHERE match_regexp(log_message, '(?i)(timeout|failed)');

输出:

idlog_levellog_message
2ERRORConnection timeout to database.
6ERRORAuthentication failed for user admin.

提取日志中的关键信息

-- 提取错误类型(假设格式为 "ERROR: [Type] message") SELECT id, log_message, -- 使用 regexp_extract 提取括号内的内容 regexp_extract(log_message, '([A-Za-z]+) failed', 1) AS error_type FROM search_docs WHERE match_regexp(log_message, 'failed');


场景 3:全文关键词搜索(match_any / match_phrase)

match_any
match_any
:任意词匹配(OR 逻辑)

-- 搜索包含 "数据" 或 "管道" 或 "实时" 的文档 -- 注意: 第三个参数必须指定 analyzer,需与索引配置一致 SELECT id, title, content FROM search_docs WHERE match_any(content, '数据 管道 实时', map('analyzer', 'chinese'));

适用场景: 宽泛搜索,只要包含任意一个关键词即命中。

match_phrase
match_phrase
:精确短语匹配

-- 搜索精确包含 "实时数据" 短语的文档 SELECT id, title, content FROM search_docs WHERE match_phrase(content, '实时数据', map('analyzer', 'chinese'));

适用场景: 精确查找固定搭配、报错信息、专有名词。

match_phrase_prefix
match_phrase_prefix
:前缀短语匹配

-- 搜索以 "实时数" 开头的短语 SELECT id, title, content FROM search_docs WHERE match_phrase_prefix(content, '实时数', map('analyzer', 'chinese'));

适用场景: 搜索建议、自动补全、模糊前缀匹配。


场景 4:综合实战 — 日志分析与告警

问题

从海量日志中快速定位 ERROR 级别的关键错误,并统计错误类型分布。

SQL 实现

WITH error_logs AS ( SELECT id, log_level, log_message, tokenize(log_message, map('analyzer', 'standard')) AS tokens FROM search_docs WHERE log_level = 'ERROR' ) SELECT id, log_message, -- 判断错误类型 CASE WHEN match_regexp(log_message, '(?i)timeout') THEN 'Connection Timeout' WHEN match_regexp(log_message, '(?i)failed') THEN 'Authentication Failed' ELSE 'Other' END AS error_category, -- 提取关键实体 filter(tokens, t -> LENGTH(t) > 3) AS important_words FROM error_logs;

输出:

idlog_messageerror_categoryimportant_words
2Connection timeout to database.Connection Timeoutconnection:timeout:database
6Authentication failed for user admin.Authentication Failedauthentication:failed:user:admin

常见问题

1.
match_*
match_*
函数必须创建倒排索引

-- 错误: 未创建索引直接调用 match_any SELECT * FROM search_docs WHERE match_any(content, '关键词', map('analyzer', 'chinese')); -- 报错: cannot infer analyzer from arguments -- 正确: 建表时声明索引(推荐) CREATE TABLE search_docs ( id BIGINT, content VARCHAR(1000), INDEX idx_content(content) USING INVERTED PROPERTIES('analyzer' = 'chinese') ); -- 插入数据后自动索引,可直接查询 -- 或存量表后建索引 CREATE INVERTED INDEX idx_content ON TABLE search_docs(content) PROPERTIES('analyzer' = 'chinese'); BUILD INDEX idx_content ON search_docs; -- 存量数据需手动构建

2.
match_*
match_*
函数必须传第三个参数

-- 错误: 缺少 analyzer 参数 match_any(content, '关键词') -- 正确: 指定 analyzer,需与索引配置一致 match_any(content, '关键词', map('analyzer', 'chinese')) match_any(content, '关键词', map('analyzer', 'auto')) -- 自动匹配索引配置

3.
tokenize
tokenize
的分析器选择

-- 中文文本必须指定 chinese 分析器,否则可能无法正确分词 tokenize('云器 Lakehouse', map('analyzer', 'chinese')) -- 输出: 云器:lakehouse tokenize('云器 Lakehouse') -- 默认分析器可能只识别英文 -- 输出: lakehouse

3. 正则表达式语法

-- match_regexp 使用 Java/PCRE 正则语法 match_regexp(log, '(?i)error') -- (?i) 忽略大小写 match_regexp(log, '\\d{3}') -- 匹配 3 位数字(注意转义)

4.
tokenize
tokenize
返回数组类型

-- 错误: 直接将数组用于字符串比较 SELECT * FROM search_docs WHERE tokenize(content) = '数据'; -- 正确: 用 explode 展开或用 array_contains 判断 SELECT * FROM search_docs WHERE array_contains(tokenize(content), '数据');


性能优化建议

场景优化策略
大文本分词先用
SUBSTR
SUBSTR
截取前 1000 字符再分词
高频搜索词建立倒排索引,避免全表扫描
正则匹配尽量用
LIKE
LIKE
替代简单正则,性能更高
分词后过滤
tokenize
tokenize
后立即
WHERE
WHERE
过滤,减少中间数据量

-- 推荐: 分词后过滤 SELECT * FROM ( SELECT id, tokenize(content, map('analyzer', 'chinese')) AS tokens FROM search_docs ) WHERE array_contains(tokens, '数据'); -- 不推荐: 全表扫描后再分词 SELECT id, tokenize(content) FROM search_docs WHERE content LIKE '%数据%';


相关文档

联系我们
预约咨询
微信咨询
电话咨询