SelectDB search():AI 日志搜索与分析场景的技术能力与实践

11 阅读9分钟

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

  • 技术实现

    -- 创建带倒排索引的日志表
    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 交集模式,减少中间物化开销

  • 技术实现

    -- 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 种查询算子能力矩阵

算子语法示例用途技术实现
TERMlevel:ERROR精确词匹配倒排索引词典查找
PHRASEerror_msg:"CUDA out of memory"短语匹配support_phrase = true,位置信息记录
PREFIXmodel_name:gpt*前缀通配倒排索引词典前缀扫描
WILDCARDerror_type:timeout*通配符匹配前缀 + 后缀匹配
REGEXPerror_msg:/CUDA.*error/正则匹配正则引擎逐行匹配
RANGElatency:[500 TO *]数值区间列存范围扫描
NOTNOT module:healthcheck排除条件查询树中排除节点
INhost:IN(gpu-01 gpu-02)多值枚举词典多 key 查找
NESTEDNESTED(steps, status:error)嵌套数组搜索配合 VARIANT 类型,穿透数组检索
BM25score()相关性排序IDF 加权 + 文档长度归一化 + TopN 存储层优化

2.4 BM25 打分与相关性排序

  • 定义:内置 BM25 评分模型(IDF 加权 + 文档长度归一化),通过 score() 列暴露评分

  • 解决的问题:搜索结果按相关性排序,避免最相关的日志被淹没在海量结果中

  • 技术实现

    SELECT 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 算"的数据搬运环节

  • 技术实现

    -- 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 + ClickHouseElasticsearch 单用
全文检索能力兼容 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 级更合适
查询延迟(搜+析)秒级(同引擎)分钟级(跨系统搬运)秒级搜索,分钟级分析
可视化生态需配合 GrafanaKibana + 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() 的条件:

  1. 日志数据量已达 TB 级,ES 存储成本成为主要矛盾
  2. 搜索和分析需求高度交织("先搜后分析"的使用模式)
  3. 中英文混合日志,中文分词是既有痛点
  4. 团队规模较小,维护 ES + OLAP 双系统吃力
  5. 已部署或计划部署 Apache Doris / SelectDB 作为分析引擎

以下情况建议评估其他方案:

  1. 纯搜索场景,几乎不需要聚合分析——ES 单用更合适
  2. 已深度绑定 ELK 生态(Kibana Dashboard 量大)——迁移代价高
  3. 数据量在 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 社区 交流更多实践。