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

使用场景

  1. 检索增强生成(RAG):为LLM提供最新、精确的知识
  2. 文本和代码搜索:基于语义相似度的搜索
  3. 推荐系统:基于内容相似度的推荐
  4. 分类:基于向量相似度的分类
  5. 聚类:文档聚类分析

开发状态

⚠️ 项目处于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)

性能优化建议

  1. 批量添加文档时,尽量使用Add方法的批量接口,而不是单条添加
  2. 对于大型集合,考虑定期调用Optimize()方法优化内部索引
  3. 搜索时合理设置返回结果数量,避免不必要的大结果集

限制

  1. chromem-go目前不支持动态调整向量维度
  2. 对于超大规模数据集(百万级以上),性能可能不如专业向量数据库
  3. 不支持分布式部署,适合单机应用场景

chromem-go是一个简单易用的嵌入式向量数据库解决方案,特别适合需要轻量级、无需外部依赖的Golang应用场景。对于更复杂的需求,可以考虑Milvus、Weaviate等专业向量数据库。

回到顶部