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 中读取二进制向量,计算余弦相似度,并结合关键词过滤,构建一个真正可用的检索系统。敬请期待!

相关推荐
IT_陈寒4 小时前
用了Proxy才发现以前的JavaScript白写了
前端·人工智能·后端
唐青枫4 小时前
别把 ArrayList 当成会自动管理内存的 List:Zig 动态数组从入门到实战
后端
鸿蒙开发4 小时前
我为 HarmonyOS 做了一个统一大模型 SDK:@hmkit/ai 正式开源
后端
猪是念来过倒4 小时前
Semaphore 与 RateLimiter:并发控制双雄详解
后端
掘金者阿豪4 小时前
异构数据同步最怕什么?不是同步慢,而是数据对不上
后端
程序员cxuan5 小时前
Claude 官方的学习教程,太强了。
人工智能·后端·程序员
老孙讲技术5 小时前
把工地遮挡和掉线接进项目部:setMessageCallback 订 alarm 与 deviceStatus
后端·物联网·音视频开发
老孙讲技术5 小时前
关店后有人进门,监控值班群却没响:用 setMessageCallback 订 human,再用 aiHuman 打开人形
后端·物联网·音视频开发
LEE5 小时前
原来 Claude Code 最厉害的工具,一行代码都不写
前端·后端
老孙讲技术6 小时前
把园区几百路摄像头收进值班台账:bindDevice 入账与 listDeviceDetailsByPage 翻页
后端·物联网·音视频开发