08_Doris 全文搜索进阶:BM25 算法与 SEARCH 函数详解

news2026/4/9 19:44:55
08_Doris 全文搜索进阶BM25 算法与 SEARCH 函数详解关键字Apache Doris、BM25算法、全文检索、SEARCH函数、倒排索引、自定义分词器、拼音检索、中文分词、相关性评分、score()函数标签Apache Doris全文搜索BM25倒排索引中文分词SEARCH函数相关性排序前言很多人对 Doris 的全文搜索能力有误解觉得它只是简单地把 Elasticsearch 的功能移植了一下其实远不止如此。Doris 的全文搜索能力经历了从 2.x 的基础倒排索引到 3.x 的高级查询算子再到 4.0 的 BM25 相关性评分 SEARCH DSL 三代演进。4.0 的全文搜索能力已经能覆盖 80% 的 Elasticsearch 使用场景同时避免了 ES 的运维复杂性和高内存消耗问题。更关键的是Doris 的全文搜索和向量搜索共享同一份存储可以在一条 SQL 里做混合检索——这是 ES 无法做到的事情。本文把 BM25 算法原理、SEARCH DSL 语法、自定义分词器配置以及生产实践中的调优技巧全部讲透。一、全文搜索能力演进1.1 三代演进路线Doris 全文搜索能力演进 ══════════════════════════════════════════════════════════ Doris 2.x基础全文检索 ├── 倒排索引引入替代原来的低效 LIKE 扫描 ├── MATCH_ALL(col, term1 term2)所有词都匹配 ├── MATCH_ANY(col, term1 term2)任一词匹配 ├── MATCH_PHRASE(col, exact phrase)短语精确匹配 └── 限制分数不支持 BM25只有 0/1 命中 Doris 3.x高级查询算子 ├── MATCH_PHRASE_PREFIX短语前缀匹配边输入边搜索 ├── MATCH_REGEXP正则表达式匹配 ├── 自定义分词器支持Tokenizer Analyzer 分离 └── 限制IDF 统计仅在 Segment 内跨 Segment 分数不可比 Doris 4.0BM25 元年 ├── BM25 相关性评分全局 IDF 统计 ├── score() 函数获取 BM25 分数用于排序 ├── SEARCH() DSL统一全文检索入口 ├── 拼音分词器4.0.2 └── SEARCH MATCH 混用支持混合评分 ══════════════════════════════════════════════════════════1.2 从 LIKE 到倒排索引为什么质变在倒排索引出现之前Doris 的全文搜索靠WHERE content LIKE %机器学习%这实际上是全表扫描在大数据量下性能极差。倒排索引改变了检索的底层机制LIKE 扫描 vs 倒排索引 LIKE %机器学习% 遍历所有行 → 对每行字符串做模式匹配 时间复杂度O(N × M)N行数M字符串长度 1 亿行 × 500 字符 → 几十亿次操作 → 分钟级 倒排索引 MATCH 机器学习 → 在倒排表中查找 → 直接获取 DocID 列表 {3, 45, 891, ...} 时间复杂度O(log(V) df)V词汇表大小df文档频率 数亿行数据 → 毫秒级二、BM25 算法深度解析2.1 从 TF-IDF 到 BM25BM25 是在 TF-IDF 基础上改进的相关性评分算法被 Elasticsearch、Lucene、Solr 等主流搜索引擎广泛采用是 2023 年之前信息检索领域的行业标准。TF-IDF 的问题TF词频随词频线性增长没有上限机器学习在文档里出现 100 次不比 10 次更有意义没有文档长度归一化长文档天然占优BM25 的改进BM25 公式 tf(q, d) × (k₁ 1) BM25(q, d) Σ IDF(q) × ─────────────────────────────── tf(q, d) k₁ × (1 - b b × |d|/avgdl) 其中 q 查询词 d 文档 tf 词频词 q 在文档 d 中出现的次数 IDF log((N - df 0.5) / (df 0.5) 1) N总文档数df包含词 q 的文档数 k₁ 词频饱和参数默认 1.2-2.0控制 TF 的增长上限 b 文档长度归一化参数默认 0.75 |d| 文档长度词数 avgdl 平均文档长度 关键改进点 1. tf 饱和处理k₁ 参数使 tf 收益递减避免词频无限权重 2. 文档长度归一化b 参数抑制长文档的天然优势直觉理解词频饱和效果示意 词权重 ↑ BM25│ ████████████趋向饱和 │ ██ │ ██ │ ██ TF-IDF│ ████████████████████线性增长 │██ └──────────────────────── 词频 tf 1 2 3 4 5 ... 100 BM25 在 tf3 后收益递减避免机器学习出现100次得分是出现1次的100倍2.2 BM25 分数的特性在使用score()函数时需要理解 BM25 分数的几个关键特性无固定量纲BM25 分数不在 0-1 范围内数值大小取决于语料库相对比较有意义同一查询下的分数可以排序不同查询间的分数不可直接比较空查询返回 0MATCH_ALL(, content)不触发 BM25 计算score() 返回 0与文档长度负相关同等词频下短文档比长文档得分高b 参数的归一化效果三、SEARCH 函数 DSL 完整语法SEARCH 函数是 Doris 4.0 新增的统一全文检索入口提供类似 Elasticsearch Query String 的 DSL 语法。3.1 基础语法-- 语法SEARCH(column,query_string[,options_json])-- 最简单的用法单词检索SELECTid,title,score()ASscoreFROMarticlesWHERESEARCH(content,机器学习)ORDERBYscoreDESC;-- 多词 AND 检索所有词必须出现WHERESEARCH(content,机器学习 AND 深度学习)-- 多词 OR 检索任一词出现即可WHERESEARCH(content,机器学习 OR 深度学习 OR 神经网络)-- NOT 排除WHERESEARCH(content,人工智能 NOT 机器人)-- 短语精确匹配双引号WHERESEARCH(content,支持向量机)-- 复杂组合WHERESEARCH(content,(机器学习 OR 深度学习) AND NOT 强化学习)3.2 指定分析器-- 使用中文分词器WHERESEARCH(content,机器学习,{analyzer: chinese})-- 使用英文分词器WHERESEARCH(title,machine learning,{analyzer: english})-- 使用拼音分词器4.0.2WHERESEARCH(title,ji qi xue xi,{analyzer: pinyin})-- 使用自定义分词器WHERESEARCH(content,技术文档,{analyzer: my_tech_analyzer})3.3 多字段搜索-- 同时在标题和正文中搜索标题权重更高SELECTid,title,(CASEWHENSEARCH(title,机器学习)THENscore()*2ELSE0ENDCASEWHENSEARCH(content,机器学习)THENscore()ELSE0END)ASweighted_scoreFROMarticlesWHERESEARCH(title,机器学习)ORSEARCH(content,机器学习)ORDERBYweighted_scoreDESC;3.4 SEARCH vs MATCH_ALL/MATCH_ANYSEARCH vs MATCH 函数对比 MATCH_ALL(col, a b c) ≈ SEARCH(col, a AND b AND c) MATCH_ANY(col, a b c) ≈ SEARCH(col, a OR b OR c) MATCH_PHRASE(col, ab) ≈ SEARCH(col, ab) 何时用 MATCH简单场景语义更清晰 何时用 SEARCH复杂 DSL需要 AND/OR/NOT 组合或从 ES 迁移四、倒排索引建立与管理4.1 创建倒排索引的完整语法-- 建表时创建倒排索引CREATETABLEarticles(idBIGINTNOTNULL,title STRING,content STRING,tags ARRAYSTRING,-- 中文全文索引INDEXidx_title(title)USINGINVERTED PROPERTIES(parserchinese,-- 中文分词support_phrasetrue,-- 支持短语查询lower_casetrue-- 大小写不敏感),INDEXidx_content(content)USINGINVERTED PROPERTIES(parserchinese,support_phrasetrue),-- 英文全文索引INDEXidx_tags(tags)USINGINVERTED PROPERTIES(parserenglish,lower_casetrue),-- 无分词索引用于精确词语检索INDEXidx_id_str(id)USINGINVERTED-- 数值类型不需要分词)DUPLICATEKEY(id)DISTRIBUTEDBYHASH(id)BUCKETS16;-- 对已有表添加索引异步构建不阻塞读写ALTERTABLEarticlesADDINDEXidx_content_v2(content)USINGINVERTED PROPERTIES(parserchinese);4.2 分析器配置Doris 支持三层分词配置分析器Analyzer三层架构 Analyzer ├── Tokenizer分词器将文本切分为 Token │ ├── standard -- 空格标点分词适合英文 │ ├── chinese -- 中文智能分词基于词典 │ ├── whitespace -- 仅按空格分词 │ ├── noop -- 不分词整段作为一个 Token │ └── char_group -- 按指定字符集分词自定义 │ ├── Token Filter过滤器对 Token 做规范化处理 │ ├── lowercase -- 转小写 │ ├── asciifolding -- 特殊字符转 ASCII │ ├── stop_word_filter -- 过滤停用词 │ ├── edge_ngram -- 生成前缀 N-gram用于前缀匹配 │ └── pinyin -- 汉字转拼音4.0.2 │ └── Character Filter字符过滤器预处理原始文本 ├── html_strip -- 去除 HTML 标签 └── pattern_replace -- 正则替换4.3 自定义分析器实战-- 场景技术文档搜索需要支持驼峰命名、下划线分词CREATEINDEXidx_codeONcode_docs(code_snippet)USINGINVERTED PROPERTIES(tokenizerchar_group,-- 按特定字符集分词char_group.typeletter_digit,-- 按字母和数字边界分词token_filterlowercase-- 统一小写);-- 效果-- getUserProfile → [get, user, profile]-- MAX_RETRY_COUNT → [max, retry, count]-- 搜索 retry 可以匹配 MAX_RETRY_COUNT-- 场景中文产品名称搜索支持拼音搜索4.0.2CREATEINDEXidx_product_nameONproducts(name)USINGINVERTED PROPERTIES(tokenizerchinese,token_filterpinyin,-- 添加拼音过滤器pinyin.first_lettertrue,-- 支持首字母缩写pinyin.padding_char );-- 效果-- 可口可乐 写入时同时生成-- 中文分词[可口可乐]-- 拼音 [ke kou ke le]-- 首字母 [kkkl]---- 以下查询都能命中-- SEARCH(name, 可口可乐) -- 中文精确-- SEARCH(name, ke kou) -- 拼音全拼-- SEARCH(name, kkkl) -- 首字母缩写五、BM25 分数实战技巧5.1 获取和使用 BM25 分数-- 基础按 BM25 相关性排序SELECTid,title,score()ASbm25_scoreFROMarticlesWHEREMATCH_ALL(content,机器学习 应用场景)ORDERBYbm25_scoreDESCLIMIT10;-- 多字段 BM25 加权-- 标题中的词权重是正文的 3 倍SELECTid,title,SUM(w)ASweighted_scoreFROM(-- 标题得分 × 3SELECTid,title,score()*3ASwFROMarticlesWHEREMATCH_ALL(title,机器学习)UNIONALL-- 正文得分 × 1SELECTid,title,score()ASwFROMarticlesWHEREMATCH_ALL(content,机器学习))tGROUPBYid,titleORDERBYweighted_scoreDESCLIMIT10;5.2 BM25 业务规则的综合排序-- 综合排序相关性 × 时效性 × 质量分数SELECTid,title,created_at,like_count,score()ASbm25_score,-- 综合得分 BM25相关性 × 时效系数 × 质量系数score()*POWER(0.95,DATEDIFF(NOW(),created_at))-- 时效性衰减每天衰减5%*LOG(1like_count)-- 质量系数对数平滑ASfinal_scoreFROMarticlesWHEREMATCH_ALL(content,机器学习 实战)ORDERBYfinal_scoreDESCLIMIT10;这种综合排序在搜索推荐系统中非常实用把纯相关性与业务指标时效、热度、质量结合起来效果远优于单纯的 BM25 排序。5.3 不同查询场景的最优策略查询场景与全文检索策略选择 ────────────────────────────────────────────────────────────── 场景 推荐方案 理由 ────────────────────────────────────────────────────────────── 精确词语搜索 MATCH_ALL score() 高效精准 模糊语义搜索 向量检索 语义理解 布尔组合搜索 SEARCH() DSL 灵活组合 中文产品/人名搜索 中文分词 拼音索引 支持拼音输入 代码/技术术语搜索 char_group 分词器 CamelCase分词 多字段加权搜索 分别计算 BM25 后加权合并 精细控制权重 混合语义关键词 Doris 混合检索BM25向量 最优质量 ──────────────────────────────────────────────────────────────六、与 Elasticsearch 的迁移对比有不少团队想把 ES 的全文搜索迁到 Doris这里给出迁移对照表Elasticsearch → Doris 全文搜索迁移对照 ES Query DSL Doris SQL ────────────────────────────────────────────────────────────── match: {content: 机器学习} MATCH_ALL(content, 机器学习) 或 SEARCH(content, 机器学习) match_phrase: 机器学习算法 MATCH_PHRASE(content, 机器学习算法) 或 SEARCH(content, 机器学习算法) multi_match: query, fields 分别对各字段建倒排索引 用多个 MATCH 条件组合 OR/AND bool: must: [A, B] WHERE MATCH_ALL(col, A) AND MATCH_ALL(col, B) should: [A, B] WHERE MATCH_ANY(col, A B) must_not: [C] WHERE NOT MATCH_ALL(col, C) query_string: A AND (B OR C) NOT D SEARCH(col, A AND (B OR C) NOT D) function_score: { 分别计算 score()在 SQL 层用公式组合 field_value_factor: like_cnt}Doris 更灵活直接 SQL 表达式 ──────────────────────────────────────────────────────────────Doris 全文搜索的优势无独立部署成本复用已有 Doris 集群与 OLAP 分析、向量检索共享存储省数据同步SQL 语法团队学习成本低Doris 全文搜索的劣势复杂嵌套 Query DSL如 nested query、percolate query还不支持Highlighting关键词高亮功能有限实时性倒排索引更新有轻微延迟取决于 Segment flush 频率七、生产实践备忘1. 分词器选择永远排在第一位建索引之前先跑分词测试看看你的数据被切成什么样的 Token。中文分词没有银弹产品名、地名、专有名词往往需要自定义词典。-- 检查分词结果4.0.2SELECTTOKENIZE(华为Mate70Pro发布,{analyzer:chinese});-- 预期[华为, mate, 70, pro, 发布]2. support_phrase 影响存储support_phrase true会额外存储 Term 的位置信息position支持短语查询但索引存储增加约 30%。如果不需要短语查询关掉可以节省空间。3. score() 只在有 MATCH 的查询里有效如果 WHERE 条件里没有全文检索条件score()返回 0。在混合查询全文 OR 向量中需要分别计算两路分数再融合。4. 并发写入时倒排索引构建是后台任务倒排索引的构建在 Compaction 时完成写入后不是立即可搜索通常有几秒到几十秒的延迟。实时性要求极高的场景需要调整 Segment flush 频率。小结Doris 4.0 的全文搜索已经不是 ES 的简陋替代品它具备了生产级的 BM25 评分、灵活的 SEARCH DSL、丰富的分词器生态中文、英文、拼音、自定义在 80% 的场景里可以完全替代 ES。最重要的价值不是它比 ES 更强而是它让全文搜索、向量搜索、结构化分析在同一个引擎里共存用 SQL 这一种语言就能完成过去需要三套系统才能做到的事情。下一篇是性能优化专题把向量检索调优、AI 函数成本控制、资源隔离策略全部系统化地讲清楚。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2500463.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…