golang轻量级嵌入式向量数据库插件chromem-go的使用
Golang轻量级嵌入式向量数据库插件chromem-go的使用
chromem-go是一个用于Go语言的嵌入式向量数据库,具有类似Chroma的接口且无第三方依赖。它支持内存存储和可选持久化。
主要特点
- 零第三方库依赖
- 嵌入式设计(类似SQLite,无需客户端-服务器模型)
- 多线程处理(利用Go原生并发特性)
- 实验性WebAssembly绑定
- 支持多种嵌入模型提供商(OpenAI、Azure OpenAI、GCP Vertex AI等)
- 支持本地模型(Ollama、LocalAI)
- 支持自定义嵌入函数
- 基于余弦相似度的精确最近邻搜索
- 文档过滤和元数据过滤功能
- 内存存储和可选持久化
安装
go get github.com/philippgille/chromem-go@latest
快速入门示例
package main
import (
"context"
"fmt"
"runtime"
"github.com/philippgille/chromem-go"
)
func main() {
ctx := context.Background()
// 创建内存数据库
db := chromem.NewDB()
// 创建集合。传递nil作为嵌入函数将使用OpenAI,需要设置"OPENAI_API_KEY"环境变量
// 也可以传递chromem.NewEmbeddingFuncOllama(...)来使用Ollama
c, err := db.CreateCollection("knowledge-base", nil, nil)
if err != nil {
panic(err)
}
// 添加文档到集合
err = c.AddDocuments(ctx, []chromem.Document{
{
ID: "1",
Content: "The sky is blue because of Rayleigh scattering.",
},
{
ID: "2",
Content: "Leaves are green because chlorophyll absorbs red and blue light.",
},
}, runtime.NumCPU()) // 使用CPU核心数作为并发数
if err != nil {
panic(err)
}
// 查询最相似的文档
res, err := c.Query(ctx, "Why is the sky blue?", 1, nil, nil)
if err != nil {
panic(err)
}
fmt.Printf("ID: %v\nSimilarity: %v\nContent: %v\n", res[0].ID, res[0].Similarity, res[0].Content)
}
输出示例:
ID: 1
Similarity: 0.6833369
Content: The sky is blue because of Rayleigh scattering.
Chroma风格的API示例
package main
import (
"context"
"github.com/philippgille/chromem-go"
)
func main() {
ctx := context.Background()
// 设置内存数据库
db := chromem.NewDB()
// 创建集合
collection, _ := db.CreateCollection("all-my-documents", nil, nil)
// 添加文档(Chroma风格API)
_ = collection.Add(ctx,
[]string{"doc1", "doc2"}, // 每个文档的唯一ID
nil, // 自动处理嵌入,也可以提供自己的嵌入
[]map[string]string{{"source": "notion"}, {"source": "google-docs"}}, // 元数据
[]string{"This is document1", "This is document2"},
)
// 查询最相似的2个结果
results, _ := collection.Query(ctx,
"This is a query document",
2,
map[string]string{"metadata_field": "is_equal_to_this"}, // 可选过滤器
map[string]string{"$contains": "search_string"}, // 可选过滤器
)
}
性能基准
在2021款Framework Laptop 13(Intel i5-1135G7, 32GB内存)上测试:
- 查询1,000个文档:约0.52ms
- 查询100,000个文档:约39.5ms
使用场景
- 检索增强生成(RAG):为LLM提供最新、精确的知识
- 文本和代码搜索:基于语义相似度的搜索
- 推荐系统:基于内容相似度的推荐
- 分类:基于向量相似度的分类
- 聚类:文档聚类分析
开发状态
⚠️ 项目处于beta阶段,v1.0.0之前可能会有破坏性变更。所有变更都会记录在CHANGELOG中。
相关项目
- Chroma:Python嵌入式向量数据库
- Pinecone、Qdrant、Milvus、Weaviate:大型客户端-服务器向量数据库
- pgvector:PostgreSQL的向量搜索扩展
- sqlite-vss:SQLite的向量搜索扩展
更多关于golang轻量级嵌入式向量数据库插件chromem-go的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang轻量级嵌入式向量数据库插件chromem-go的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Chromem-go: Golang轻量级嵌入式向量数据库插件使用指南
chromem-go是一个轻量级的嵌入式向量数据库插件,专为Golang应用程序设计,特别适合需要本地向量存储和检索的场景。下面我将详细介绍它的使用方法和示例代码。
安装
首先安装chromem-go:
go get github.com/philippgille/chromem-go
基本使用
1. 创建集合(Collection)
package main
import (
"fmt"
"github.com/philippgille/chromem-go"
)
func main() {
// 创建或加载集合
collection, err := chromem.NewCollection("my-collection", nil)
if err != nil {
panic(err)
}
defer collection.Close()
// 集合信息
fmt.Printf("集合名称: %s\n", collection.Name())
fmt.Printf("向量维度: %d\n", collection.Dimension())
}
2. 添加文档和向量
// 假设我们已经创建了collection
// 准备文档
documents := []chromem.Document{
{
ID: "doc1",
Content: "Go语言是一种静态强类型、编译型语言",
Metadata: map[string]interface{}{
"author": "Google",
"year": 2009,
},
},
{
ID: "doc2",
Content: "Rust语言注重安全性和并发性能",
Metadata: map[string]interface{}{
"author": "Mozilla",
"year": 2010,
},
},
}
// 假设我们有这些文档的向量表示
vectors := [][]float32{
{0.1, 0.2, 0.3, 0.4}, // doc1的向量
{0.5, 0.6, 0.7, 0.8}, // doc2的向量
}
// 添加文档和向量到集合
err := collection.Add(documents, vectors)
if err != nil {
panic(err)
}
fmt.Println("文档添加成功")
3. 向量相似度搜索
// 假设我们有一个查询向量
queryVector := []float32{0.15, 0.25, 0.35, 0.45}
// 搜索最相似的3个文档
results, err := collection.Search(queryVector, 3, nil)
if err != nil {
panic(err)
}
fmt.Println("搜索结果:")
for i, result := range results {
fmt.Printf("%d. ID: %s, 相似度: %.4f, 内容: %s\n",
i+1,
result.Document.ID,
result.Similarity,
result.Document.Content)
}
高级功能
1. 持久化存储
// 创建带持久化的集合
persistDir := "./chromem-data"
collection, err := chromem.NewCollection("persistent-collection", &chromem.CollectionConfig{
PersistDirectory: &persistDir,
})
if err != nil {
panic(err)
}
defer collection.Close()
// 后续操作会自动持久化到指定目录
2. 带过滤条件的搜索
// 创建过滤条件
filter := func(metadata map[string]interface{}) bool {
// 只返回year大于等于2010的文档
if year, ok := metadata["year"].(int); ok {
return year >= 2010
}
return false
}
// 带过滤条件的搜索
results, err := collection.Search(queryVector, 3, filter)
if err != nil {
panic(err)
}
3. 集合统计信息
// 获取集合统计信息
stats := collection.Stats()
fmt.Printf("文档总数: %d\n", stats.DocumentCount)
fmt.Printf("向量维度: %d\n", stats.Dimension)
fmt.Printf("创建时间: %v\n", stats.CreatedAt)
性能优化建议
- 批量添加文档时,尽量使用
Add
方法的批量接口,而不是单条添加 - 对于大型集合,考虑定期调用
Optimize()
方法优化内部索引 - 搜索时合理设置返回结果数量,避免不必要的大结果集
限制
- chromem-go目前不支持动态调整向量维度
- 对于超大规模数据集(百万级以上),性能可能不如专业向量数据库
- 不支持分布式部署,适合单机应用场景
chromem-go是一个简单易用的嵌入式向量数据库解决方案,特别适合需要轻量级、无需外部依赖的Golang应用场景。对于更复杂的需求,可以考虑Milvus、Weaviate等专业向量数据库。