掘金 人工智能 18小时前
使用 Node.js + OpenAI + MongoDB 实现文本向量知识库搜索
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

本文介绍如何利用Node.js、OpenAI Embedding API和MongoDB构建一个轻量级的文本向量知识库搜索系统。该系统支持语义检索和相似内容召回,实现了从原始文档到文本分块、OpenAI向量生成、存储至MongoDB,再到用户查询和相似内容检索的完整流程。文章还提供了本地语义检索的实现方法,并介绍了如何通过MongoDB Atlas向量搜索来提升搜索性能,为构建智能问答和AI搜索系统提供了基础。

💡 **环境准备与依赖安装**:搭建该文本向量知识库系统,需要准备Node.js 18+环境、MongoDB本地或Atlas云服务,以及OpenAI API Key。通过npm安装axios、mongodb和dotenv等依赖,并配置.env文件,设置OpenAI API密钥和MongoDB URI。

🧱 **文本切分与向量存储**:系统首先将文档按固定长度切分为片段(chunk),然后通过OpenAI API将文本片段转化为向量。这些向量随后被存储在MongoDB中,为后续的语义检索提供数据基础。代码示例展示了如何使用Node.js和OpenAI API进行文本切分和向量生成,并存入MongoDB。

🔍 **本地语义检索**:用户输入问题后,系统获取问题的向量,并计算其与数据库中所有向量的相似度,使用余弦相似度算法。系统返回最相关的文本内容。该方法通过计算向量之间的相似度,实现了基于语义的搜索,而非关键词匹配。

🚀 **MongoDB Atlas向量搜索**:文章介绍了如何使用MongoDB Atlas的向量索引来提升搜索性能。通过创建向量索引,可以优化搜索效率。修改检索逻辑,使用MongoDB Atlas的$vectorSearch操作符进行向量搜索,从而实现更高效的相似内容检索。

向量搜索(Vector Search)是构建智能问答、AI 搜索系统的基础能力。本文将介绍如何使用 Node.js、OpenAI Embedding API 和 MongoDB,实现一个轻量级的文本向量知识库搜索系统,支持语义检索和相似内容召回。

目标

实现一个可执行的完整流程:

原始文档 → 文本分块→ OpenAI 向量生成→ 存入 MongoDB → 用户查询 → 相似内容检索

📦 环境准备

安装依赖

npm install axios mongodb dotenv

.env 配置:

OPENAI_API_KEY=你的OpenAI密钥MONGO_URI=mongodb://localhost:27017

文本切分与向量存储

我们将文档按固定长度切分为片段(chunk),再通过 OpenAI API 转为向量,并存入 MongoDB。

// index.jsrequire('dotenv').config();const axios = require('axios');const { MongoClient } = require('mongodb');const OPENAI_API_KEY = process.env.OPENAI_API_KEY;const MONGO_URI = process.env.MONGO_URI;const splitText = (text, size = 200) =>  Array.from({ length: Math.ceil(text.length / size) },    (_, i) => text.slice(i * size, (i + 1) * size));async function getEmbedding(text) {  const res = await axios.post(    'https://api.openai.com/v1/embeddings',    { input: text, model: 'text-embedding-ada-002' },    { headers: { Authorization: `Bearer ${OPENAI_API_KEY}` } }  );  return res.data.data[0].embedding;}async function storeChunks(chunks) {  const client = new MongoClient(MONGO_URI);  await client.connect();  const col = client.db('vector_store').collection('docs');  for (const chunk of chunks) {    const embedding = await getEmbedding(chunk);    await col.insertOne({ chunk, embedding });  }  await client.close();}(async () => {  const text = '这是一个用于测试的知识库文档,将被切分并转为向量存储。';  const chunks = splitText(text);  await storeChunks(chunks);})();

本地语义检索(余弦相似度)

用户输入问题后,我们获取其向量并与数据库中所有向量计算相似度,返回最相关的内容。

// search.jsconst similarity = (a, b) =>  a.reduce((sum, val, i) => sum + val * b[i], 0) /  (Math.hypot(...a) * Math.hypot(...b));async function search(query, topK = 3) {  const client = new MongoClient(MONGO_URI);  await client.connect();  const col = client.db('vector_store').collection('docs');  const docs = await col.find({}).toArray();  const queryVec = await getEmbedding(query);  const results = docs    .map(doc => ({ ...doc, score: similarity(queryVec, doc.embedding) }))    .sort((a, b) => b.score - a.score)    .slice(0, topK);  for (const r of results) {    console.log(`\n[Score: ${r.score.toFixed(4)}]`);    console.log(r.chunk);  }  await client.close();}search('向量存储是什么?');

使用 MongoDB Atlas 向量搜索(可选)

如果使用 MongoDB Atlas,可开启原生向量索引,提升搜索性能。

向量索引配置(Atlas → Search Index → Create Index)

{  "fields": {    "embedding": {      "type": "vector",      "dimensions": 1536,      "similarity": "cosine"    }  }}

修改检索逻辑:

const pipeline = [  {    $vectorSearch: {      index: "vector_index",      path: "embedding",      queryVector: queryVec,      numCandidates: 100,      limit: topK    }  },  {    $project: {      chunk: 1,      score: { $meta: "vectorSearchScore" }    }  }];const results = await col.aggregate(pipeline).toArray();

本项目实现了一个基础的文本向量知识库,具备以下能力:

Fish AI Reader

Fish AI Reader

AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

FishAI

FishAI

鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

联系邮箱 441953276@qq.com

相关标签

Node.js MongoDB 向量搜索 OpenAI Embedding
相关文章