Node.js + LangChain +React:搭建个人知识库(四)- 把向量和文件切块存入mysql中

前面已经完成BGE模型本地加载和文档切片的大坑,成功拿到了文档的向量化数据。

今天这篇不聊虚的,直接进入数据持久化 阶段------把切好的块和算好的向量,稳稳当当地存进MySQL。同时,我也顺手把 @xenova/transformers 库中那些容易被忽视的 env 配置参数做了一个深度整理。

填坑必备:Transformers.js 的 env 配置参数全解

在上一篇加载本地模型时,我们用到了 env.localModelPathenv.allowRemoteModels。其实在 Node.js 环境下,@xenova/transformers 提供了一套非常灵活的环境配置系统(完全对应 Python 版本的逻辑)。

这里我把常用的 env 参数整理成了一份清单,方便大家日后查阅和配置:

参数名 默认值 作用说明
allowRemoteModels true 核心开关 。设为 false 时,强制不联网,只走本地或缓存(离线环境必配)。
allowLocalModels true 设为 false 时,跳过本地检查,直接尝试远程下载(调试新版本时有用)。
remoteHost https://huggingface.co 换源关键 。如果你想用 HF 的国内镜像站(如 https://hf-mirror.com),改这里即可,无需修改模型ID。
localModelPath ./models 指定本地模型存放的根目录。代码中引用模型时仍用模型ID,它会自动去这个目录下找。
cacheDir ./.cache 下载模型时的临时缓存目录。
useFSCache true 是否启用文件系统缓存。
useCustomCache false 高级用法。如果你想把模型缓存到 Redis 或数据库,设为 true 并实现下方的 customCache 对象。
customCache null 需要实现 Web 标准的 Cache 接口(matchput 方法)。

关于换源的小贴士:

正如表格中提到的,昨天有朋友提醒,在 Node 中配置 env.remoteHost 应该就可以实现换源。确实,理论上这是最优雅的方式,但我目前为了绝对的稳定,依然采用了**"手动下载模型 + 配置 localModelPath"**的笨办法。如果你的网络环境较好,强烈建议试试直接改 remoteHost,能省去手动下载的步骤。

核心实操:如何在 MySQL 中高效存储向量?

既然我们在第三篇已经决定"退守 MySQL",那就得解决一个核心问题:MySQL 原生不支持向量类型,怎么存?

很多教程会建议你直接把向量转成 JSON 字符串(如 "[0.1, 0.5, ...]")存进 TEXTJSON 字段。但我实测后发现,这种方式不仅占用空间大,而且后续读取出来做相似度计算时,字符串转数组的开销也非常大。

最终方案:使用 BLOB(二进制大对象)存储。

将 JavaScript 中的 Float32Array(向量数据)直接转换为二进制 Buffer 存入数据库。

代码实现(TypeScript/Node.js):

ini 复制代码
// 将数据转换为Float32Buffer
const convertToFloat32Buffer = data => {
  const float32Array = new Float32Array(data);
  return Buffer.from(float32Array.buffer);
};

这种"土办法"的优势非常明显:

  • 节省空间:相比于存 JSON 字符串,二进制存储能节省约 60% 的磁盘空间。
  • 读写极快:数据库对二进制字段的 I/O 优化通常比解析长文本要好,且 Node.js 处理 Buffer 的效率极高。

架构升级预告:引入"任务"概念

细心的朋友可能已经发现了,向量化是一个非常消耗 CPU 和时间的过程。如果文档很大,或者并发请求进来,直接同步处理会导致 Node.js 服务卡死。

因此,在这一阶段,我们需要引入**"任务队列"**的概念:

  1. 用户上传文档 -> 立即返回"上传成功,正在处理中"。
  2. 后台生成任务 -> 将文档解析、切片、向量化封装成一个异步任务。
  3. 持久化到 DB -> 任务完成后,将向量写入 MySQL。

虽然这一篇没有贴具体的任务队列代码,但请务必在设计之初就预留好这个接口。

总结

这一篇虽然"技术含量"看起来不如前几篇高,但数据持久化是 RAG 项目从"玩具"变成"工具"的关键一步。

我们解决了两个核心问题:

  1. 怎么存:利用 MySQL 的二进制字段存储向量,兼顾了成本与性能。
  2. 怎么配:理清了 transformers.jsenv 对象的配置逻辑,为后续的模型管理打下基础。

下一篇文章,我们将迎来一个小高潮:实现全文检索。我们将从 MySQL 中读取二进制向量,计算余弦相似度,并结合关键词过滤,构建一个真正可用的检索系统。敬请期待!

相关推荐
爱勇宝1 分钟前
《道德经》第 7 章:真正厉害的领导者,不抢主角
前端·后端·程序员
用户208046804561 分钟前
Python3 条件控制新手实战指南
后端
HONG````20 分钟前
HarmonyOS ArkUI RelativeContainer 相对定位布局:ID 锚点与 alignRules 实战
后端
Conan在掘金26 分钟前
�鸿蒙报错速查:Cannot find name 'AppStorageV2',忘 import 编译就炸,根因 + 眜解法
后端
夏雪coding28 分钟前
Dify 自定义插件实战:FastAPI + localtunnel 30 分钟搭一个天气查询工具
后端·ai编程
用户693717500138432 分钟前
Claude Code终端日志Token占用实测:一个过滤器砍掉60%-90%
android·前端·后端
前端双越老师42 分钟前
如何以前端视角(非0基础)学 Java ?
java·node.js·全栈
dear_bi_MyOnly1 小时前
【SpringBoot配置文件】
java·spring boot·后端·学习·spring·java-ee·学习方法
一缕清烟在人间1 小时前
HarmonyOS应用开发实战:萌宠日记 - 健康提醒列表与动态数据绑定
后端
HONG````1 小时前
HarmonyOS 6.1 实战:Stack 层叠布局与 Overlay 浮层详解
后端