golang向量数据库嵌入管理与搜索插件库Milvus的使用

Golang向量数据库嵌入管理与搜索插件库Milvus的使用

Milvus是一个高性能的向量数据库,专为大规模向量搜索而设计。它可以帮助开发者高效地组织和搜索非结构化数据,如文本、图像和多模态信息。

Milvus简介

Milvus是用Go和C++编写的,支持CPU/GPU硬件加速,提供一流的向量搜索性能。它具有完全分布式和K8s原生架构,可以水平扩展,处理数十亿向量的搜索查询,并支持实时流式更新。

milvus banner

Golang中使用Milvus的完整示例

以下是一个完整的Golang示例,展示如何使用Milvus进行向量搜索:

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() {
	// 1. 连接到Milvus服务器
	ctx := context.Background()
	milvusClient, err := client.NewGrpcClient(ctx, "localhost:19530")
	if err != nil {
		log.Fatal("failed to connect to Milvus:", err.Error())
	}
	defer milvusClient.Close()

	// 2. 创建集合
	collectionName := "demo_collection"
	schema := &entity.Schema{
		CollectionName: collectionName,
		Description:    "test collection",
		Fields: []*entity.Field{
			{
				Name:       "id",
				DataType:   entity.FieldTypeInt64,
				PrimaryKey: true,
				AutoID:     false,
			},
			{
				Name:     "vector",
				DataType: entity.FieldTypeFloatVector,
				TypeParams: map[string]string{
					"dim": "128", // 向量维度
				},
			},
		},
	}

	err = milvusClient.CreateCollection(ctx, schema, 2) // 2是分片数
	if err != nil {
		log.Fatal("failed to create collection:", err.Error())
	}

	// 3. 插入数据
	ids := []int64{1, 2, 3}
	vectors := [][]float32{
		{0.1, 0.2, 0.3, /* ... 128维向量 */},
		{0.4, 0.5, 0.6, /* ... 128维向量 */},
		{0.7, 0.8, 0.9, /* ... 128维向量 */},
	}

	idColumn := entity.NewColumnInt64("id", ids)
	vectorColumn := entity.NewColumnFloatVector("vector", 128, vectors)

	_, err = milvusClient.Insert(ctx, collectionName, "", idColumn, vectorColumn)
	if err != nil {
		log.Fatal("failed to insert data:", err.Error())
	}

	// 4. 创建索引
	index, err := entity.NewIndexIvfFlat(entity.L2, 128) // L2距离, IVF_FLAT索引
	if err != nil {
		log.Fatal("failed to create index:", err.Error())
	}

	err = milvusClient.CreateIndex(ctx, collectionName, "vector", index, false)
	if err != nil {
		log.Fatal("failed to create index:", err.Error())
	}

	// 5. 加载集合到内存
	err = milvusClient.LoadCollection(ctx, collectionName, false)
	if err != nil {
		log.Fatal("failed to load collection:", err.Error())
	}

	// 6. 搜索向量
	queryVector := []float32{0.1, 0.2, 0.3 /* ... 128维向量 */}
	vectorsCol := entity.NewColumnFloatVector("vector", 128, [][]float32{queryVector})

	sp, _ := entity.NewIndexIvfFlatSearchParam(10) // nprobe=10
	searchResult, err := milvusClient.Search(
		ctx,
		collectionName,
		[]string{},
		"",
		[]string{"id"},
		[]entity.Vector{vectorsCol},
		"vector",
		entity.L2,
		10, // topK=10
		sp,
	)
	if err != nil {
		log.Fatal("failed to search:", err.Error())
	}

	// 7. 处理搜索结果
	for _, result := range searchResult {
		fmt.Println("IDs:", result.IDs)
		fmt.Println("Scores:", result.Scores)
	}

	// 8. 清理资源
	err = milvusClient.DropCollection(ctx, collectionName)
	if err != nil {
		log.Fatal("failed to drop collection:", err.Error())
	}
}

示例代码说明

  1. 连接Milvus:使用NewGrpcClient连接到Milvus服务器
  2. 创建集合:定义包含ID和向量字段的集合模式
  3. 插入数据:准备ID和向量数据并插入集合
  4. 创建索引:为向量字段创建IVF_FLAT索引
  5. 加载集合:将集合加载到内存以便搜索
  6. 搜索向量:使用查询向量进行相似性搜索
  7. 处理结果:打印搜索到的ID和相似度分数
  8. 清理资源:删除测试集合

Milvus的主要特点

  1. 高性能和大规模支持:分布式架构,分离计算和存储
  2. 多种向量索引类型:支持HNSW、IVF、FLAT、SCANN等
  3. 灵活的租户管理:支持数据库、集合、分区级别的隔离
  4. 稀疏向量支持:支持全文搜索和混合搜索
  5. 数据安全:用户认证、TLS加密和RBAC

安装Milvus Go SDK

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

Milvus是构建AI应用程序(如文本/图像搜索、RAG和推荐系统)的强大工具。通过Go SDK,开发者可以轻松地将向量搜索功能集成到自己的应用中。


更多关于golang向量数据库嵌入管理与搜索插件库Milvus的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang向量数据库嵌入管理与搜索插件库Milvus的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


Golang与Milvus向量数据库集成指南

Milvus是一款开源的向量数据库,专门用于处理大规模向量相似性搜索。下面我将介绍如何在Golang中使用Milvus进行向量嵌入的管理和搜索。

1. 安装Milvus Go SDK

首先需要安装Milvus的Go SDK:

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

2. 连接Milvus服务

package main

import (
	"context"
	"fmt"
	"time"

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

func main() {
	// 创建Milvus客户端
	ctx := context.Background()
	milvusClient, err := client.NewGrpcClient(ctx, "localhost:19530")
	if err != nil {
		panic("failed to connect to milvus:" + err.Error())
	}
	defer milvusClient.Close()

	// 检查连接状态
	err = milvusClient.Connect(ctx)
	if err != nil {
		panic("failed to connect:" + err.Error())
	}
	
	fmt.Println("Connected to Milvus successfully!")
}

3. 创建集合(Collection)

func createCollection(milvusClient client.Client, collectionName string) {
	// 定义schema
	schema := &entity.Schema{
		CollectionName: collectionName,
		Description:    "test collection",
		AutoID:         false,
		Fields: []*entity.Field{
			{
				Name:       "id",
				DataType:   entity.FieldTypeInt64,
				PrimaryKey: true,
				AutoID:     false,
			},
			{
				Name:     "vector",
				DataType: entity.FieldTypeFloatVector,
				TypeParams: map[string]string{
					"dim": "128", // 向量维度
				},
			},
			{
				Name:     "text",
				DataType: entity.FieldTypeVarChar,
				TypeParams: map[string]string{
					"max_length": "256",
				},
			},
		},
	}

	// 创建集合
	err := milvusClient.CreateCollection(ctx, schema, 2) // 2是分片数
	if err != nil {
		panic("failed to create collection:" + err.Error())
	}
	
	fmt.Println("Collection created successfully!")
}

4. 插入向量数据

func insertData(milvusClient client.Client, collectionName string) {
	// 准备数据
	ids := []int64{1, 2, 3}
	vectors := [][]float32{
		make([]float32, 128), // 实际应用中替换为真实向量
		make([]float32, 128),
		make([]float32, 128),
	}
	texts := []string{"first text", "second text", "third text"}

	// 转换为Milvus可识别的列数据
	idColumn := entity.NewColumnInt64("id", ids)
	vectorColumn := entity.NewColumnFloatVector("vector", 128, vectors)
	textColumn := entity.NewColumnVarChar("text", texts)

	// 插入数据
	_, err := milvusClient.Insert(ctx, collectionName, "", idColumn, vectorColumn, textColumn)
	if err != nil {
		panic("failed to insert data:" + err.Error())
	}
	
	fmt.Println("Data inserted successfully!")
	
	// 刷新数据使可搜索
	err = milvusClient.Flush(ctx, collectionName, false)
	if err != nil {
		panic("failed to flush data:" + err.Error())
	}
}

5. 创建索引

func createIndex(milvusClient client.Client, collectionName string) {
	// 定义IVF_FLAT索引
	idx, err := entity.NewIndexIvfFlat(entity.L2, 128) // L2距离, 128个聚类中心
	if err != nil {
		panic("failed to create index:" + err.Error())
	}

	// 在向量字段上创建索引
	err = milvusClient.CreateIndex(ctx, collectionName, "vector", idx, false)
	if err != nil {
		panic("failed to create index:" + err.Error())
	}
	
	fmt.Println("Index created successfully!")
}

6. 向量搜索

func search(milvusClient client.Client, collectionName string, queryVector []float32) {
	// 加载集合到内存
	err := milvusClient.LoadCollection(ctx, collectionName, false)
	if err != nil {
		panic("failed to load collection:" + err.Error())
	}

	// 构建搜索参数
	sp, _ := entity.NewIndexIvfFlatSearchParam(10) // 搜索最近邻的10个聚类中心
	
	// 执行搜索
	results, err := milvusClient.Search(
		ctx,
		collectionName,
		nil, // 分区列表
		"",  // 表达式
		[]string{"id", "text"}, // 输出字段
		[]entity.Vector{entity.FloatVector(queryVector)}, // 查询向量
		"vector", // 向量字段名
		entity.L2, // 距离度量
		5, // 返回topK结果
		sp, // 搜索参数
	)
	if err != nil {
		panic("failed to search:" + err.Error())
	}

	// 处理结果
	for _, result := range results {
		for _, score := range result.Scores {
			fmt.Printf("Score: %f\n", score)
		}
		for _, field := range result.Fields {
			switch field.Name() {
			case "id":
				fmt.Printf("IDs: %v\n", field.(*entity.ColumnInt64).Data())
			case "text":
				fmt.Printf("Texts: %v\n", field.(*entity.ColumnVarChar).Data())
			}
		}
	}
}

7. 完整示例

func main() {
	ctx := context.Background()
	collectionName := "test_collection"
	
	// 1. 连接Milvus
	milvusClient, err := client.NewGrpcClient(ctx, "localhost:19530")
	if err != nil {
		panic("failed to connect to milvus:" + err.Error())
	}
	defer milvusClient.Close()
	
	// 2. 创建集合
	createCollection(milvusClient, collectionName)
	
	// 3. 插入数据
	insertData(milvusClient, collectionName)
	
	// 4. 创建索引
	createIndex(milvusClient, collectionName)
	
	// 5. 搜索
	queryVector := make([]float32, 128) // 替换为真实查询向量
	search(milvusClient, collectionName, queryVector)
}

8. 最佳实践

  1. 批量插入:Milvus适合批量插入数据,建议每次插入至少1000条记录
  2. 索引选择:根据场景选择合适的索引类型,IVF_FLAT适合精确搜索,HNSW适合近似搜索
  3. 资源管理:搜索完成后及时释放集合内存
  4. 参数调优:根据数据规模和性能需求调整nlist和nprobe参数

9. 注意事项

  1. Milvus服务需要提前启动
  2. 向量维度在创建集合时确定后不能修改
  3. 搜索前需要确保数据已刷新并加载到内存
  4. 生产环境建议使用用户名密码认证连接

以上代码提供了Golang中使用Milvus的基本操作流程,实际应用中需要根据具体需求进行调整和优化。

回到顶部