跳转至

向量数据库教程

概述

向量数据库是专门存储和检索向量数据的数据库,是构建RAG、推荐系统、图像检索等应用的核心组件。

为什么需要向量数据库

# 传统数据库 vs 向量数据库

传统数据库(MySQL/PostgreSQL)
- 基于精确匹配查询
- 适合结构化数据
- SQL查询

向量数据库
- 基于相似度查询
- 适合非结构化数据(文本、图像)
- 语义检索

主流向量数据库对比

数据库 特点 适用场景 价格
FAISS 高效,Facebook开源 本地部署 免费
Chroma 轻量级,易用 原型开发 免费
Pinecone 云服务,托管 生产环境 付费
Weaviate GraphQL,多模态 复杂应用 开源+云
Milvus 分布式,高性能 大规模数据 开源
Qdrant Rust实现,高性能 生产环境 开源+云

FAISS

基础使用

import faiss
import numpy as np

# 创建向量维度
dimension = 128

# 创建索引
index = faiss.IndexFlatL2(dimension)

# 生成示例数据
vectors = np.random.random((1000, dimension)).astype('float32')

# 添加向量
index.add(vectors)

print(f"索引中的向量数量: {index.ntotal}")

# 查询
query = np.random.random((1, dimension)).astype('float32')
distances, indices = index.search(query, k=5)

print(f"最近的5个向量: {indices}")
print(f"对应距离: {distances}")

索引类型

# 1. Flat索引(精确搜索)
index_flat = faiss.IndexFlatL2(dimension)

# 2. IVF索引(倒排文件索引)
quantizer = faiss.IndexFlatL2(dimension)
index_ivf = faiss.IndexIVFFlat(quantizer, dimension, 100)

# 3. HNSW索引(图索引)
index_hnsw = faiss.IndexHNSWFlat(dimension, 32)

# 4. PQ索引(乘积量化)
index_pq = faiss.IndexPQ(dimension, 8, 8)

与LangChain集成

from langchain_community.vectorstores import FAISS
from langchain_openai import OpenAIEmbeddings

# 创建向量库
embeddings = OpenAIEmbeddings()
vectorstore = FAISS.from_texts(
    texts=["文档1内容", "文档2内容", "文档3内容"],
    embedding=embeddings
)

# 检索
docs = vectorstore.similarity_search("查询内容", k=3)

# 保存/加载
vectorstore.save_local("faiss_index")
vectorstore = FAISS.load_local("faiss_index", embeddings)

Chroma

安装配置

pip install chromadb

基础使用

import chromadb

# 创建客户端
client = chromadb.Client()

# 创建集合
collection = client.create_collection("my_collection")

# 添加文档
collection.add(
    documents=["文档1", "文档2", "文档3"],
    ids=["id1", "id2", "id3"],
    metadatas=[
        {"source": "网页"},
        {"source": "PDF"},
        {"source": "数据库"}
    ]
)

# 查询
results = collection.query(
    query_texts=["查询内容"],
    n_results=3
)

print(results)

持久化存储

import chromadb

# 持久化客户端
client = chromadb.PersistentClient(path="./chroma_db")

# 或使用指定目录
client = chromadb.Client(Settings(
    chroma_db_impl="duckdb+parquet",
    persist_directory="./chroma_db"
))

与LangChain集成

from langchain_community.vectorstores import Chroma
from langchain_openai import OpenAIEmbeddings

# 创建向量库
vectorstore = Chroma.from_documents(
    documents=docs,
    embedding=OpenAIEmbeddings(),
    persist_directory="./chroma_db"
)

# 检索
retriever = vectorstore.as_retriever(search_kwargs={"k": 3})
docs = retriever.invoke("查询内容")

Pinecone

安装配置

pip install pinecone-client

基础使用

from pinecone import Pinecone, ServerlessSpec

# 初始化
pc = Pinecone(api_key="your-api-key")

# 创建索引
pc.create_index(
    name="my-index",
    dimension=1536,
    metric="cosine",
    spec=ServerlessSpec(
        cloud="aws",
        region="us-east-1"
    )
)

# 连接索引
index = pc.Index("my-index")

# 插入向量
index.upsert(
    vectors=[
        {"id": "vec1", "values": [0.1]*1536, "metadata": {"text": "文档1"}},
        {"id": "vec2", "values": [0.2]*1536, "metadata": {"text": "文档2"}}
    ]
)

# 查询
results = index.query(
    vector=[0.1]*1536,
    top_k=3,
    include_metadata=True
)

与LangChain集成

from langchain_pinecone import PineconeVectorStore
from langchain_openai import OpenAIEmbeddings

# 创建向量库
vectorstore = PineconeVectorStore(
    index_name="my-index",
    embedding=OpenAIEmbeddings(),
    text_key="text"
)

# 检索
docs = vectorstore.similarity_search("查询内容", k=3)

Weaviate

安装配置

pip install weaviate-client

Docker部署

docker run -d \
  --name weaviate \
  -p 8080:8080 \
  -p 50051:50051 \
  cr.weaviate.io/semitechnologies/weaviate:latest

基础使用

import weaviate

# 创建客户端
client = weaviate.Client("http://localhost:8080")

# 创建类
client.schema.create_class({
    "class": "Document",
    "vectorizer": "text2vec-transformers",
    "properties": [
        {
            "name": "content",
            "dataType": ["text"]
        },
        {
            "name": "source",
            "dataType": ["string"]
        }
    ]
})

# 添加数据
client.data_object.create(
    class_name="Document",
    data_object={
        "content": "这是一篇关于AI的文章",
        "source": "网站"
    }
)

# 向量搜索
result = client.query.get("Document", ["content", "source"]) \
    .with_near_text({"concepts": ["人工智能"]}) \
    .with_limit(5) \
    .do()

与LangChain集成

from langchain_weaviate import WeaviateVectorStore
from langchain_openai import OpenAIEmbeddings

# 创建向量库
vectorstore = WeaviateVectorStore.from_documents(
    documents=docs,
    embedding=OpenAIEmbeddings(),
    weaviate_url="http://localhost:8080"
)

# 检索
docs = vectorstore.similarity_search("查询内容")

Milvus

安装配置

pip install pymilvus

Docker部署

# 使用Milvus Lite
pip install milvus

# 或使用Docker Compose
docker-compose up -d

基础使用

from pymilvus import connections, Collection, FieldSchema, CollectionSchema, DataType

# 连接Milvus
connections.connect("default", host="localhost", port="19530")

# 定义字段
fields = [
    FieldSchema(name="id", dtype=DataType.INT64, is_primary=True, auto_id=True),
    FieldSchema(name="embedding", dtype=DataType.FLOAT_VECTOR, dim=128),
    FieldSchema(name="text", dtype=DataType.VARCHAR, max_length=200)
]

# 创建集合
schema = CollectionSchema(fields, description="文档集合")
collection = Collection("documents", schema)

# 插入数据
import numpy as np
data = [
    np.random.random((100, 128)).tolist(),
    [f"文档{i}" for i in range(100)]
]
collection.insert(data)

# 创建索引
index_params = {
    "metric_type": "L2",
    "index_type": "IVF_FLAT",
    "params": {"nlist": 1024}
}
collection.create_index("embedding", index_params)

# 搜索
collection.load()
results = collection.search(
    data=np.random.random((1, 128)).tolist(),
    anns_field="embedding",
    param={"metric_type": "L2", "params": {"nprobe": 16}},
    limit=5,
    output_fields=["text"]
)

性能优化

索引选择指南

# 索引类型选择

精确搜索(小数据集 <10K)
- IndexFlatL2

平衡性能(中等数据集 10K-100K)
- IndexIVFFlat
- IndexHNSWFlat

大规模数据(>100K)
- IndexIVFPQ
- IndexHNSW

查询优化

# 1. 使用余弦相似度而非L2
# 适合文本等高维稀疏数据

# 2. 调整搜索参数
results = index.search(
    query,
    k=10,
    params={"nprobe": 32}  # IVF索引的搜索范围
)

# 3. 使用批量查询
results = index.search(batch_queries, k=10)

内存优化

# 1. 使用PQ压缩
index = faiss.IndexPQ(dimension, 8, 8)

# 2. 使用IVF+PQ
index = faiss.IndexIVFPQ(quantizer, dimension, 100, 8, 8)

# 3. 分片存储
# 对于超大规模数据,使用分布式方案

选型建议

# 选择向量数据库

本地开发/原型验证 → Chroma
大规模生产环境 → Milvus
云原生托管 → Pinecone
多模态应用 → Weaviate
高性能本地 → FAISS + Qdrant

下一步学习

  1. RAG检索增强生成教程 - 构建RAG系统
  2. LangChain框架教程 - 集成向量数据库
  3. 大语言模型原理 - 理解嵌入模型