16-向量数据库Weaviate:语义搜索的底层原理

33 阅读1分钟

向量数据库Weaviate:语义搜索的底层原理

前言

向量数据库是RAG系统的核心。本文深入讲解Weaviate的工作原理和使用方法。

适合读者: AI工程师、数据工程师


一、向量搜索原理

文本 → Embedding模型 → 向量(768维数组)

相似度计算:
- 余弦相似度
- 欧氏距离
- 点积

示例:
"苹果" → [0.89, 0.72, 0.91, ...]
"橙子" → [0.71, 0.73, 0.82, ...]
余弦相似度 = 0.92(非常相似)

二、Weaviate Schema设计

import weaviate

client = weaviate.Client("http://localhost:8080")

schema = {
    "class": "ServiceTicket",
    "vectorizer": "none",  # 使用外部Embedding
    "properties": [
        {
            "name": "ticket_id",
            "dataType": ["string"]
        },
        {
            "name": "title",
            "dataType": ["text"]
        },
        {
            "name": "content",
            "dataType": ["text"]
        },
        {
            "name": "category",
            "dataType": ["string"]
        }
    ]
}

client.schema.create_class(schema)

三、数据导入

from langchain_community.embeddings import OllamaEmbeddings

embeddings = OllamaEmbeddings(model="nomic-embed-text")

# 批量导入
with client.batch as batch:
    for doc in documents:
        # 生成向量
        vector = embeddings.embed_query(doc['content'])
        
        # 添加对象
        batch.add_data_object(
            {
                "ticket_id": doc['ticket_id'],
                "title": doc['title'],
                "content": doc['content'],
                "category": doc['category']
            },
            "ServiceTicket",
            vector=vector
        )

四、向量检索

# 1. 向量搜索
query = "如何重置密码"
query_vector = embeddings.embed_query(query)

result = client.query.get(
    "ServiceTicket",
    ["ticket_id", "title", "content"]
).with_near_vector({
    "vector": query_vector
}).with_limit(5).do()

# 2. 混合搜索(向量+关键词)
result = client.query.get(
    "ServiceTicket",
    ["ticket_id", "title", "content"]
).with_hybrid(
    query=query,
    alpha=0.5  # 0=纯关键词,1=纯向量
).with_limit(5).do()

# 3. 过滤搜索
result = client.query.get(
    "ServiceTicket",
    ["ticket_id", "title", "content"]
).with_near_vector({
    "vector": query_vector
}).with_where({
    "path": ["category"],
    "operator": "Equal",
    "valueString": "账号管理"
}).with_limit(5).do()

五、性能优化

# HNSW索引配置
schema = {
    "class": "ServiceTicket",
    "vectorIndexConfig": {
        "ef": 200,              # 提高召回率
        "efConstruction": 256,  # 构建时的精度
        "maxConnections": 64    # 每个节点的最大连接数
    }
}

下一篇预告: 《Embedding技术详解:文本如何变成数字向量》