恐怖解谜密室逃脱
109.73M · 2026-03-09
在大模型、AI Agent、RAG应用爆火的当下,非结构化数据的处理与检索成为开发者的核心痛点。传统关系型数据库擅长结构化数据的CRUD,却难以应对文本、图片、音视频等高维向量数据的相似度检索,而Milvus作为开源云原生向量数据库,完美补齐了这一短板,成为AI应用的核心基础设施。
本文将带你吃透Milvus核心知识,结合Node.js实战代码,手把手搭建AI日记语义检索系统,从理论到落地,一站式掌握Milvus的使用技巧。
我们熟知的MySQL、PostgreSQL等关系型数据库,核心是处理结构化数据,通过SQL语句实现增删改查,依赖关键词匹配完成检索。但面对AI场景下的海量非结构化数据,这些数据库就显得力不从心:
Milvus是由Zilliz团队主导的开源云原生向量数据库,专为高维向量数据的存储、索引、相似度检索设计,完美适配AI场景,核心优势一目了然:
| 对比维度 | 传统关系型数据库 | Milvus向量数据库 |
|---|---|---|
| 核心数据类型 | 结构化数据(数字、字符串) | 高维向量+结构化元数据 |
| 检索方式 | 关键词匹配、精确查询 | 向量相似度检索、语义匹配 |
| 核心场景 | 常规业务CRUD、数据统计 | AI语义检索、RAG、推荐、多模态搜索 |
| 性能特点 | 高并发结构化读写 | 海量向量毫秒级相似检索 |
简单来说,传统数据库管“结构化数据”,Milvus管“AI向量数据” ,二者搭配才能打造完整的AI应用体系。
理论落地才是硬道理,接下来结合实战代码,基于Node.js+Milvus+OpenAI Embeddings,搭建一个AI日记语义检索项目,实现按语义搜索日记内容的功能。
npm install @zilliz/milvus2-sdk-node dotenv @langchain/openai
# Milvus连接配置
MILVUS_ADDRESS=你的Milvus服务地址
MILVUS_TOKEN=你的Milvus令牌
# OpenAI嵌入模型配置
OPENAI_API_KEY=你的OpenAI API Key
OPENAI_BASE_URL=OpenAI接口地址
EMBEDDING_MODEL_NAME=text-embedding-3-large
代码核心逻辑:连接Milvus → 定义向量嵌入函数 → 创建集合与索引 → 插入日记数据 → 语义检索日记,贴合实际开发流程,每一步都做了详细注释。
import {
MilvusClient,
DataType,
IndexType,
MetricType
} from '@zilliz/milvus2-sdk-node'
import 'dotenv/config'
import {
OpenAIEmbeddings
} from '@langchain/openai'
// 配置常量:向量维度、集合名称
const VECTOR_DIM = 1024;
const COLLECTION_NAME = 'ai_diary';
// Milvus连接参数
const TOKEN = process.env.MILVUS_TOKEN;
const ADDRESS = process.env.MILVUS_ADDRESS;
// 初始化OpenAI嵌入模型,将文本转为向量
const embeddings = new OpenAIEmbeddings({
apiKey: process.env.OPENAI_API_KEY,
model: process.env.EMBEDDING_MODEL_NAME,
configuration: {
baseURL: process.env.OPENAI_BASE_URL,
},
dimensions: VECTOR_DIM,
})
// 初始化Milvus客户端
const client = new MilvusClient({
address: ADDRESS,
token: TOKEN,
})
// 封装向量嵌入函数:文本转高维向量
async function getEmbeddings(text) {
const result = await embeddings.embedQuery(text);
return result;
}
// 主函数:项目核心逻辑
async function main() {
// 1. 检测Milvus连接状态
console.log('正在连接Milvus...');
const checkHealth = await client.checkHealth();
if (!checkHealth.isHealthy) {
console.error('Milvus连接失败:', checkHealth.reasons);
return;
}
console.log('连接成功, 集群状态正常...');
// 2. 测试语义检索:查询户外活动相关日记
const query ='我想看看关于户外活动的日记';
const queryVector=await getEmbeddings(query);
const searchResult =await client.search({
collection_name:COLLECTION_NAME,
vector:queryVector,
limit:3, // 返回Top3相似结果
metric_type:MetricType.COSINE, // 余弦相似度
output_fields:['id','content','date','mood','tags'], // 返回字段
})
// 打印检索结果
searchResult.results.forEach(result => {
console.log(`n 日记ID: ${result.id}`);
console.log(`内容: ${result.content}`);
console.log(`日期: ${result.date}`);
console.log(`心情: ${result.mood}`);
console.log(`标签: ${result.tags}`);
})
console.log('n 搜索结果:');
console.log(`共找到 ${searchResult.results.length} 条相关日记`);
// 3. 创建Milvus集合:定义数据结构
await client.createCollection({
collection_name: COLLECTION_NAME,
fields: [
{ name: 'id', data_type: DataType.VarChar, max_length: 50, is_primary_key: true },
{ name: 'vector', data_type: DataType.FloatVector, dim: VECTOR_DIM }, // 向量字段
{ name: 'content', data_type: DataType.VarChar, max_length: 5000 }, // 日记内容
{ name: 'date', data_type: DataType.VarChar, max_length: 50 }, // 日记日期
{ name: 'mood', data_type: DataType.VarChar, max_length: 50 }, // 心情
{ name: 'tags', data_type: DataType.Array, element_type: DataType.VarChar,
max_capacity: 10, max_length: 50} // 标签数组
]
})
// 4. 创建向量索引:提升检索效率
await client.createIndex({
collection_name: COLLECTION_NAME,
field_name: 'vector',
index_type: IndexType.IVF_FLAT,
metric_type: MetricType.COSINE,
params: {
nlist: VECTOR_DIM,
}
})
// 5. 加载集合:使集合可读写
await client.loadCollection({
collection_name: COLLECTION_NAME,
})
// 6. 准备日记数据并插入
console.log('nInserting diary entries...');
const diaryContents = [
{
id: 'diary_001',
content: '今天天气很好,去公园散步了,心情愉快。看到了很多花开了,春天真美好。',
date: '2026-01-10',
mood: 'happy',
tags: ['生活', '散步']
},
{
id: 'diary_002',
content: '今天工作很忙,完成了一个重要的项目里程碑。团队合作很愉快,感觉很有成就感。',
date: '2026-01-11',
mood: 'excited',
tags: ['工作', '成就']
},
{
id: 'diary_003',
content: '周末和朋友去爬山,天气很好,心情也很放松。享受大自然的感觉真好。',
date: '2026-01-12',
mood: 'relaxed',
tags: ['户外', '朋友']
},
{
id: 'diary_004',
content: '今天学习了 Milvus 向量数据库,感觉很有意思。向量搜索技术真的很强大。',
date: '2026-01-12',
mood: 'curious',
tags: ['学习', '技术']
},
{
id: 'diary_005',
content: '晚上做了一顿丰盛的晚餐,尝试了新菜谱。家人都说很好吃,很有成就感。',
date: '2026-01-13',
mood: 'proud',
tags: ['美食', '家庭']
}
];
console.log('Generating embeddings...');
// 批量生成向量并插入Milvus
const diaryData = await Promise.all(
diaryContents.map(async (diary) => ({
...diary,
vector: await getEmbeddings(diary.content),
}))
);
const inserRes = await client.insert({
collection_name: COLLECTION_NAME,
data: diaryData,
})
console.log(`插入成功: ${inserRes.insert_cnt} 条数据`);
}
// 执行主函数
main();
Milvus的能力远不止语义检索,它是AI应用的“万能底座”,覆盖绝大多数AI场景:
在AI全面落地的时代,向量数据库已经成为开发者的必备技能,而Milvus凭借开源、高性能、易扩展的优势,成为向量数据库的首选方案。
本文从理论到实战,拆解了Milvus的核心知识,通过Node.js实战项目带你上手向量检索,不管是AI Agent、RAG应用还是语义搜索,Milvus都能轻松支撑。后续还可以深入学习Milvus分布式部署、索引调优、混合检索等进阶技能,进一步优化AI应用性能。
互动时刻:你在开发AI应用时,遇到过哪些向量检索的问题?欢迎在评论区留言交流~
本文已同步收录至个人掘金专栏,持续更新AI开发、向量数据库、大模型实战干货,欢迎点赞、收藏、关注~