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; -- 为存量数据构建
场景 1:文本分词与词频统计(tokenize)
问题
对中文/英文混合文本进行分词,统计高频词汇。
SQL 实现
-- 使用中文分析器分词
SELECT
id,
title,
tokenize(content, map('analyzer', 'chinese')) AS tokens
FROM search_docs
WHERE id IN (1, 2, 3);
输出:
id
title
tokens
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;
输出:
token
freq
数据
4
实现
3
分析
2
支持
2
实时
2
...
...
关键说明:
tokenize
tokenize
返回数组类型,需用
explode
explode
展开为多行才能聚合统计。
场景 2:正则表达式匹配(match_regexp)
问题
从日志消息中提取特定格式的错误码或 IP 地址。
SQL 实现
-- 匹配包含 "timeout" 或 "failed" 的日志
SELECT id, log_level, log_message
FROM search_docs
WHERE match_regexp(log_message, '(?i)(timeout|failed)');
输出:
id
log_level
log_message
2
ERROR
Connection timeout to database.
6
ERROR
Authentication failed for user admin.
说明:
(?i)
(?i)
表示忽略大小写。
match_regexp
match_regexp
不需要倒排索引,直接对字符串进行正则匹配。
提取日志中的关键信息
-- 提取错误类型(假设格式为 "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)
前提: 需在
content
content
列创建倒排索引。
CREATE INVERTED INDEX idx_content ON TABLE search_docs(content);
-- 搜索精确包含 "实时数据" 短语的文档
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;
输出:
id
log_message
error_category
important_words
2
Connection timeout to database.
Connection Timeout
connection:timeout:database
6
Authentication failed for user admin.
Authentication Failed
authentication: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; -- 存量数据需手动构建
-- 错误: 直接将数组用于字符串比较
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 '%数据%';