当前位置: 首页 > news >正文

fastgpt 社区版探究:mongo db 全文检索算法探秘

近几日在研究fast gpt 的源码,对于它的混合检索比较好奇:全文检索是怎么实现的?向量检索呢?

看了源码才了解到,实际上fastgpt 支持三种向量库,一是minlvs , 二是 pgsql vector, 三是oceanbase(阿里的)。

向量检索,以pgvector为例简单说一下,就是在pg库里加载了pgvector插件,在postgresql 库中创建了 modeldata 的表,其中有字段名为 vector,类型也是vector,就存储切块后的内容的向量值。是1536维的,据说在精准度和计算量之间达到了一个比较好的平衡。

建立向量索引,以及搜索算法,都是pgvector所支持的,不再细说。

令我好奇的是,其全文检索是基于mongo db内置的来实现的。从源码来看,用到了jieba 分词,将句子分此后,用空格连接,以便兼容mongo db的算法(按照英文习惯,单词之间用空格分隔)。这说明实际上原始内容存储到mongo db的数据库字段里,也应该是经过分词后,将每个词之间采用空格分开的。

那么,接下来我的疑问便是,其内部究竟是怎么实现的。为此我求助了腾讯元宝的DeepSeek深度搜索,提示词如下:

假如在 mongo db 中存储了文章的内容,并对内容字段建立了全文检索的索引,那么加入搜索一个经过中文分词后的句子“中国 汽车 品牌 世界 最强”,在mongo db 内部是怎么进行检索并对检索结果进行打分的?假如有个记录的内容是 “中国的汽车品牌 是世界上最强的没有之一” ,另一个是“日本汽车比不上中国汽车”, 它们各自的得分会是多少?这个得分是按照内容包含了相应的关键字就得分呢?还是关键字在其中出现次数多也有助于高的得分呢?还是怎么样的?

以下便是值得记录的它的回答:

MongoDB 的全文检索基于 ​​倒排索引​​ 和 ​​TF-IDF 算法​​ 进行匹配和打分。以下是针对你问题的详细分析:


​一、检索过程解析​

​1. 索引构建​
  • 对文章内容字段建立全文索引后,MongoDB 会:

    1. ​分词​​:将文本拆分为词元(如 ["中国", "汽车", "品牌", "世界", "最强"])。

    2. ​构建倒排索引​​:记录每个词元出现的文档位置及频率。

      "中国" → [文档1_ID, 文档2_ID]
      "汽车" → [文档1_ID, 文档2_ID]
      "品牌" → [文档1_ID]
      "世界" → [文档1_ID]
      "最强" → [文档1_ID]
​2. 查询处理​
  • 查询 中国 汽车 品牌 世界 最强被拆分为独立词元。

  • MongoDB 执行 ​​OR 逻辑​​:匹配包含任意查询词元的文档(除非使用 ""指定短语)。


​二、相关性打分机制​

得分由 ​​TF-IDF 算法​​ 计算,公式简化如下:

Score = TF(词频) × IDF(逆文档频率)
​1. TF (词频)​
  • ​词在文档中出现的次数越高,得分越高​​。

  • 示例:

    • 文档1:"中国的汽车品牌是世界上最强的没有之一"

      • 中国:1, 汽车:1, 品牌:1, 世界:1, 最强:1

    • 文档2:"日本汽车比不上中国汽车"

      • 中国:1, 汽车:2(其他词未出现)

​2. IDF (逆文档频率)​
  • ​词在整个集合中的稀有程度​​。词越常见,IDF 越低。

  • 公式:

    IDF = log(总文档数 / 包含该词的文档数)
  • 假设集合中有 1000 篇文档:

    • 汽车出现在 800 篇 → IDF = log(1000/800) ≈ 0.1

    • 最强出现在 10 篇 → IDF = log(1000/10) ≈ 2.0

​3. 最终得分计算​
  • ​文档1​​:

    Score = (TF_中国 × IDF_中国) + (TF_汽车 × IDF_汽车) + ... ≈ (1×0.2) + (1×0.1) + (1×1.5) + (1×0.3) + (1×2.0) = 4.1
  • ​文档2​​:

    Score = (TF_中国 × IDF_中国) + (TF_汽车 × IDF_汽车) ≈ (1×0.2) + (2×0.1) = 0.4

✅ ​​结论​​:文档1 得分远高于文档2,因为它包含更多查询词元且包含高 IDF 词(如“最强”)。


​三、其他影响因素​

  1. ​词元位置与权重​​:

    • 标题中的词可能比正文权重更高(取决于索引配置)。

  2. ​短语匹配​​:

    • 若查询用引号包裹 "中国汽车",连续出现的短语会获得额外加分。

  3. ​停用词过滤​​:

    • “的”、“是”等停用词会被忽略,不计入打分。

  4. ​词干提取​​:

    • 英文中“running”会被归并为“run”,中文需依赖分词工具(如你的代码中的 jiebaSplit)。


​四、你的示例结果对比​

文档内容

匹配词元

TF-IDF 得分

原因分析

中国的汽车品牌是世界上最强的没有之一

中国、汽车、品牌、世界、最强

较高 (如4.1)

命中全部查询词元,且包含高 IDF 词(如“最强”)

日本汽车比不上中国汽车

中国、汽车

较低 (如0.4)

仅命中2个词元,且“汽车”因常见导致 IDF 低


​关键结论​

  • ​命中词元数量​​和​​词元的稀有度​​(IDF)是得分的核心因素。

  • 代码中的 score: { $meta: 'textScore' }正是获取这个 TF-IDF 分数。

  • 中文场景需依赖分词工具(如你的 jiebaSplit)预处理查询词,否则 MongoDB 默认按空格分词(对中文不友好)。

ok,本篇结束。感谢AI 的回复。

http://www.dtcms.com/a/494370.html

相关文章:

  • 防爆手机与普通手机有什么区别?防爆手机哪个牌子好?
  • 聊聊 Unity(小白专享、C# 小程序 之 日历、小闹钟)
  • 在vscode中全选后,同时在每行行尾,开始多行编辑(Mac版)
  • C4D域的重要修改层之延迟衰减和量化之解析
  • 建设银行网站网址是什么柳州电商网站建设
  • 记录WinFrom 使用 Autoupdater.NET.Official 进行软件升级更新,避免遗忘
  • 【汇编】RAX,eax,ax,ah,al 关系
  • 苍穹外卖 Day12 实战总结:Apache POI 实现 Excel 报表导出全流程解析
  • 网站分页符怎么做珠海网站建设哪个好薇
  • Redis的Docker安装
  • Windows 11 24H2 图形化安装 Docker Desktop(自定义安装路径到 D 盘)
  • python+uniapp基于微信小程序的瑜伽体验课预约系统
  • 什么是Bug呢?
  • 怎么制作网站记事本嘉兴网络科技有限公司
  • 外贸网站建设有用吗做外贸常用那几个网站
  • 【小白笔记】在 PyTorch 和 NumPy 这样的张量库中,形状(Shape) (3,) 的真正含义
  • 新版视频直播点播平台EasyDSS用视频破局,获客转化双提升
  • 【OS笔记07】:进程和线程5-进程的同步与互斥
  • 基于Session和Redis实现短信验证码登录
  • 视觉Slam14讲笔记第6讲非线性优化
  • 仓库管理系统:定义、需求和​​类型
  • 项目管理进阶——解读 软件质量体系白皮书【附全文阅读】
  • ARQC生成模拟
  • 网站架构演变过程ui和网页设计
  • ASR+LLM:B站学习视屏下载并生成学习笔记
  • C++中的引用
  • Linux 系统下 ZONE 区域的划分
  • 网站内部链接优化方法cpanel伪静态wordpress
  • LangChain 表达式语言核心组合:Prompt + LLM + OutputParser
  • 【管理多版本Python环境】Anaconda安装及使用