Skip to content

向量数据库 (Vector Database)

Embedding 搞定后,我们需要把这些向量存起来,并支持快速的最近邻搜索 (ANN)。这就需要用到向量数据库。

常用向量数据库选型

数据库类型语言优势适用场景
Milvus专用向量库Go/C++高性能、云原生、功能全海量数据 (亿级),企业级生产环境
Qdrant专用向量库Rust易用、支持混合检索中大规模,追求开发体验
Weaviate专用向量库Go模块化、自带 Embedding需要一体化解决方案
PgvectorPG 插件C运维简单,复用 PG数据量不大 (<千万级),已有 PG 设施

在 Golang 生态中,MilvusWeaviate 是原生 Go 开发的,SDK 支持非常完善。

Milvus 实战 (Golang SDK)

Milvus 是目前最流行的开源向量数据库之一。

1. 安装 SDK

bash
go get -u github.com/milvus-io/milvus-sdk-go/v2

2. 连接与创建 Collection

go
package main

import (
	"context"
	"fmt"
	"log"

	"github.com/milvus-io/milvus-sdk-go/v2/client"
	"github.com/milvus-io/milvus-sdk-go/v2/entity"
)

func main() {
	ctx := context.Background()

	// 1. 连接 Milvus
	c, err := client.NewClient(ctx, client.Config{
		Address: "localhost:19530",
	})
	if err != nil {
		log.Fatal("failed to connect to milvus:", err)
	}
	defer c.Close()

	// 2. 定义 Schema
	collectionName := "rag_knowledge_base"
	schema := &entity.Schema{
		CollectionName: collectionName,
		Description:    "RAG 知识库",
		Fields: []*entity.Field{
			{
				Name:       "id",
				DataType:   entity.FieldTypeInt64,
				PrimaryKey: true,
				AutoID:     true,
			},
			{
				Name:     "embedding",
				DataType: entity.FieldTypeFloatVector,
				TypeParams: map[string]string{
					"dim": "1536", // 对应 OpenAI embedding 维度
				},
			},
			{
				Name:     "content",
				DataType: entity.FieldTypeVarChar,
				TypeParams: map[string]string{
					"max_length": "65535",
				},
			},
		},
	}

	// 3. 创建 Collection
	err = c.CreateCollection(ctx, schema, entity.DefaultShardNumber)
	if err != nil {
		log.Println("collection 可能已存在:", err)
	}
	
	// 4. 创建索引 (IVF_FLAT)
	idx, _ := entity.NewIndexIvfFlat(entity.L2, 1024)
	c.CreateIndex(ctx, collectionName, "embedding", idx, false)
	
	// 5. 加载到内存
	c.LoadCollection(ctx, collectionName, false)
	
	fmt.Println("Milvus 初始化完成")
}

3. 插入数据

go
func InsertData(c client.Client, vectors [][]float32, contents []string) {
	// 列式存储构造数据
	idCol := entity.NewColumnInt64("id", nil) // AutoID 不需要填
	embeddingCol := entity.NewColumnFloatVector("embedding", 1536, vectors)
	contentCol := entity.NewColumnVarChar("content", contents)

	_, err := c.Insert(context.Background(), "rag_knowledge_base", "", idCol, embeddingCol, contentCol)
	if err != nil {
		log.Fatal(err)
	}
}
go
func Search(c client.Client, queryVec []float32) {
	sp, _ := entity.NewIndexIvfFlatSearchParam(10) // nprobe

	searchResult, err := c.Search(
		context.Background(),
		"rag_knowledge_base",
		[]string{}, // partitions
		"",         // expr (标量过滤条件)
		[]string{"content"}, // output fields
		[]entity.Vector{entity.FloatVector(queryVec)},
		"embedding", // vector field
		entity.L2,   // metric type
		3,           // topK
		sp,
	)
	
	if err != nil {
		log.Fatal(err)
	}

	for _, result := range searchResult {
		for i := 0; i < result.ResultCount; i++ {
			content, _ := result.Fields.GetColumn("content").GetAsString(i)
			score := result.Scores[i]
			fmt.Printf("Top%d Score: %f Content: %s\n", i, score, content)
		}
	}
}

总结

向量数据库是 RAG 的长期记忆体

  • 对于 Demo,用 langchaingo/vectorstores/memory 即可。
  • 对于生产环境,Milvus 是 Golang 开发者的首选,性能强劲且 SDK 友好。

🚀 学习遇到瓶颈?想进大厂?

看完这篇技术文章,如果还是觉得不够系统,或者想在实战中快速提升?
王中阳的就业陪跑训练营,提供定制化学习路线 + 企业级实战项目 + 简历优化 + 模拟面试。

了解训练营详情