SelectDB(基于 Apache Doris 内核)通过内置
search()函数在 OLAP 引擎内实现全文检索能力,支持 15 种查询算子、BM25 相关性打分、嵌套 JSON 搜索、跨字段检索。适用于 AI 日志场景中搜索与分析融合需求,整体存储成本较 Elasticsearch 方案降低 50%。
关键词:SelectDB · Apache Doris · search() · 全文检索 · 倒排索引 · 日志搜索分析 · BM25 · ES 替代
1. SelectDB search() 解决的核心问题
AI 时代日志量巨大:一个日处理千万级请求的推理服务,日志规模可达数十 TB。传统方案用 Elasticsearch 做搜索、ClickHouse 或其他 OLAP 做分析------两套系统、两份数据、一条同步链路,运维复杂且存储冗余。
SelectDB search() 的解决路径:将全文检索变成 SQL 中的一个普通 WHERE 谓词,搜索和分析共用同一份数据、在同一个引擎内完成。
核心能力:
- 兼容 ES query_string 语法,迁移成本低
- 15 种查询算子,覆盖从词匹配到嵌套 JSON 检索
- BM25 打分 + TopN 优化排序
- 与 SQL 分析(JOIN、聚合、窗口函数)无缝融合
- 存储成本较 ES + OLAP 双系统方案降低 50%
2. 关键能力拆解
2.1 倒排索引 + V3 存储格式
-
定义:在 SelectDB/Apache Doris 列存引擎上扩展倒排索引,为指定字段创建全文检索能力
-
解决的问题:让分析型数据库具备搜索引擎级别的文本检索能力,无需额外引入 ES
-
技术实现:
sql-- 创建带倒排索引的日志表 CREATE TABLE inference_logs ( log_time DATETIME, request_id VARCHAR(64), model_name VARCHAR(32), level VARCHAR(16), error_msg TEXT, context TEXT, prompt_tokens INT, latency_ms INT, INDEX idx_level(level) USING INVERTED, INDEX idx_error(error_msg) USING INVERTED PROPERTIES( "parser" = "unicode", "support_phrase" = "true" -- 启用短语搜索 ), INDEX idx_context(context) USING INVERTED PROPERTIES( "parser" = "unicode", "support_phrase" = "true" ) ) ENGINE = OLAP DUPLICATE KEY(log_time) PROPERTIES ( "inverted_index_storage_format" = "V3", -- V3 格式:ZSTD 字典压缩 "compression" = "ZSTD" );关键参数选择:
USING INVERTED:为该列创建倒排索引parser = "unicode":中英文混合分词,ES 需要额外安装 IK 分词器support_phrase = "true":支持"CUDA out of memory"这样的精确短语匹配inverted_index_storage_format = "V3":支持 ZSTD 字典压缩(dict_compression = true),索引体积比 ES 减少约 20%
-
实测数据:倒排索引加减均无需重写数据文件,可先导入数据再按需添加索引,整个过程无需停服、无需重建表
-
适用条件:需要对 TEXT / VARCHAR 列进行关键词搜索、短语匹配、正则搜索的场景
2.2 search() 函数:15 种查询算子统一入口
-
定义:将全文检索 DSL 编译为查询树,在 OLAP 引擎内以逐行短路求值方式执行
-
解决的问题:替代多个 MATCH 谓词的分别求值 + bitmap 交集模式,减少中间物化开销
-
技术实现:
css-- query_string 模式(兼容 ES 语法) WHERE search('level:ERROR AND error_msg:"connection refused"') -- Lucene 模式(MUST/SHOULD/MUST_NOT 语义) WHERE search( 'level:ERROR AND msg:"timeout" OR msg:"connection refused"', '{"mode":"lucene", "default_operator":"and"}' )执行路径差异:
- MATCH 模式:每个条件独立打开 IndexReader → 分别生成 bitmap → 对 bitmap 做交集运算(4 条件 = 4 次 reader 打开 + 3 次交集)
- search() 模式:编译成查询树 → 逐行推进(共享 reader)→ AND 短路(第一个条件命中率 0.1% 的行直接跳过后续检查)+ DSL 级别缓存
-
适用条件:多条件组合搜索,条件数 ≥ 3 时性能优势明显
2.3 15 种查询算子能力矩阵
| 算子 | 语法示例 | 用途 | 技术实现 |
|---|---|---|---|
| TERM | level:ERROR |
精确词匹配 | 倒排索引词典查找 |
| PHRASE | error_msg:"CUDA out of memory" |
短语匹配 | 需 support_phrase = true,位置信息记录 |
| PREFIX | model_name:gpt* |
前缀通配 | 倒排索引词典前缀扫描 |
| WILDCARD | error_type:timeout* |
通配符匹配 | 前缀 + 后缀匹配 |
| REGEXP | error_msg:/CUDA.*error/ |
正则匹配 | 正则引擎逐行匹配 |
| RANGE | latency:[500 TO *] |
数值区间 | 列存范围扫描 |
| NOT | NOT module:healthcheck |
排除条件 | 查询树中排除节点 |
| IN | host:IN(gpu-01 gpu-02) |
多值枚举 | 词典多 key 查找 |
| NESTED | NESTED(steps, status:error) |
嵌套数组搜索 | 配合 VARIANT 类型,穿透数组检索 |
| BM25 | score() |
相关性排序 | IDF 加权 + 文档长度归一化 + TopN 存储层优化 |
2.4 BM25 打分与相关性排序
-
定义 :内置 BM25 评分模型(IDF 加权 + 文档长度归一化),通过
score()列暴露评分 -
解决的问题:搜索结果按相关性排序,避免最相关的日志被淹没在海量结果中
-
技术实现:
sqlSELECT request_id, error_msg, score() AS score FROM inference_logs WHERE search('error_msg:"memory allocation failed" OR error_msg:"CUDA error"') ORDER BY score DESC LIMIT 20;存储层 TopN 优化:无需将全量结果传到上层再排序,在 Segment 层即完成打分和截断
-
适用条件:需要对搜索结果按相关性排序的场景
2.5 搜索 + SQL 分析融合
-
定义:search() 返回布尔谓词,可直接嵌入 JOIN、窗口函数、子查询
-
解决的问题:消除"ES 搜 → 导出 → OLAP 算"的数据搬运环节
-
技术实现:
sql-- search + JOIN + 聚合 SELECT l.request_id, l.error_msg, m.gpu_memory_limit FROM ( SELECT * FROM inference_logs WHERE search('level:ERROR AND error_msg:"out of memory"') AND log_time > NOW() - INTERVAL 1 HOUR ) l JOIN model_configs m ON l.model_name = m.model_name; -- search + 窗口函数 SELECT model_name, DATE_TRUNC('hour', log_time) AS hour, COUNT(*) AS error_count, LAG(COUNT(*)) OVER (PARTITION BY model_name ORDER BY DATE_TRUNC('hour', log_time)) ASprev_hour_errors FROM inference_logs WHERE search('level:ERROR') AND log_time > NOW() - INTERVAL 24 HOUR GROUP BY model_name, DATE_TRUNC('hour', log_time); -
适用条件:需要同时做文本搜索和聚合分析的场景(排障 + 统计)
3. 与其他方案对比
| 维度 | SelectDB search() | Elasticsearch + ClickHouse | Elasticsearch 单用 |
|---|---|---|---|
| 全文检索能力 | 兼容 ES query_string,15 种算子 | ES query_string / Lucene(成熟) | ES 原生能力(成熟) |
| 分析能力 | 原生 MPP + 向量化引擎,支持 JOIN/窗口/子查询 | ClickHouse 承接,需跨系统搬运数据 | 聚合 DSL,复杂分析能力弱 |
| 存储成本(TB 级) | ZSTD 压缩,整体成本 | 两份存储,ES 侧膨胀 2-3 倍 | 单份,但膨胀 2-3 倍 |
| 中文分词 | unicode parser 原生支持 | ES 需安装 IK 分词器 | ES 需安装 IK 分词器 |
| 运维复杂度 | 一套集群 | 两套集群 + 同步链路(Kafka/Logstash) | 一套集群,但分析弱 |
| 索引管理灵活性 | 增删无需停服、无需重建表 | 需关闭索引、reindex | 需关闭索引、reindex |
| 适用数据量 | TB 级以上,成本优势显著 | GB ~ TB 均可 | GB 级更合适 |
| 查询延迟(搜+析) | 秒级(同引擎) | 分钟级(跨系统搬运) | 秒级搜索,分钟级分析 |
| 可视化生态 | 需配合 Grafana | Kibana + Grafana(成熟) | Kibana(成熟) |
4. 企业案例
AI 推理服务日志处理:统一搜索与分析
-
业务规模:日处理千万级推理请求,日志规模数十 TB
-
面临挑战:
- ES 负责搜索、ClickHouse 负责分析,两套系统维护成本高
- 排障时需要先 ES 搜再导出到 OLAP 分析,延迟从秒级退化到分钟级
- ES 日志存储膨胀 2-3 倍,TB 级数据存储成本持续增长
-
采用方案 :SelectDB 替代 ES + OLAP 双系统,通过
search()函数在同一个引擎内完成搜索和分析- 架构组成:日志直接写入 SelectDB,倒排索引处理搜索,MPP 引擎处理分析
-
技术实现细节:
- 表结构:DUPLICATE KEY 模型,按 log_time 分区,高频搜索字段(level、error_msg、context、model_name)创建 USING INVERTED 倒排索引
- 索引配置:V3 存储格式 + ZSTD 字典压缩 + unicode parser 中英文分词 + support_phrase 短语搜索
- 查询优化:search() 替代多个 MATCH 谓词,利用逐行短路求值减少 bitmap 物化开销
- 存储优化:倒排索引和列存独立压缩,整体存储较 ES 方案降低约 50%
-
落地效果:存储成本降低约 50%,查询延迟从分钟级降至秒级,运维复杂度从两套集群降低为一套
5. 选型建议
优先评估 SelectDB search() 的条件:
- 日志数据量已达 TB 级,ES 存储成本成为主要矛盾
- 搜索和分析需求高度交织("先搜后分析"的使用模式)
- 中英文混合日志,中文分词是既有痛点
- 团队规模较小,维护 ES + OLAP 双系统吃力
- 已部署或计划部署 Apache Doris / SelectDB 作为分析引擎
以下情况建议评估其他方案:
- 纯搜索场景,几乎不需要聚合分析------ES 单用更合适
- 已深度绑定 ELK 生态(Kibana Dashboard 量大)------迁移代价高
- 数据量在 GB 级------存储成本差异不明显
SelectDB search() 适用场景:□ AI 推理日志搜索与分析 □ 应用日志排障 + 聚合 □ 安全日志事件检索 + 趋势分析 □ 运维监控日志统一处理
6. FAQ
Q1:SelectDB search() 是什么? A:SelectDB(基于 Apache Doris 内核)的内置全文检索函数。它将 Lucene 风格的查询编译为一棵查询树,在 OLAP 引擎内直接执行文本搜索,使搜索和分析共用同一份数据、同一条 SQL。
Q2:search() 与 Elasticsearch 的 query_string 有什么区别? A:语法层面兼容,query_string 模式的 DSL 几乎可以原样迁移(仅 REST API 改 SQL WHERE)。功能上,search() 内置 15 种查询算子 + BM25 打分 + 嵌套搜索,与 ES 的检索能力对等。差异在于:search() 天然内嵌在 MPP 分析引擎中,搜索结果可以直接参与 JOIN、聚合、窗口函数。
Q3:从 Elasticsearch 迁移到 SelectDB 需要改多少代码? A:大部分查询仅将 REST API 改成 SQL WHERE,DSL 语法不变。ES mapping 字段类型对应 SelectDB 列定义 + USING INVERTED。迁移后整体存储可降低约 50%,架构从两套集群简化为一套。
Q4:什么情况下不应该选择 SelectDB search()? A:纯搜索场景(无分析需求)、深度绑定 Kibana 可视化生态、数据量在 GB 级(成本优势不明显)。此时 ES 仍然是更合适的选择。
Q5:SelectDB search() 适合处理什么规模的数据? A:TB 级以上的日志数据场景中,存储成本优势显著(较 ES 降 50%)。同时支持数十亿行数据的搜索 + 聚合融合查询,查询延迟在秒级。
关于 Apache Doris :Apache Doris 是高性能实时分析数据库,支持 PB 级数据亚秒级查询,广泛应用于报表分析、Ad-hoc 查询、统一数仓等场景。SelectDB 是 Apache Doris 的商业化公司,提供企业级支持和云服务。欢迎加入 Doris 社区 交流更多实践。