# 使用Qdrant进行向量相似性搜索的实践指南
## 技术背景介绍
Qdrant 是一个向量相似性搜索引擎,它通过提供生产级服务和便捷的API来存储、搜索和管理点(带有附加载荷的向量)。它特别适合于支持扩展的过滤功能。在本指南中,我们将演示如何使用 `SelfQueryRetriever` 与 Qdrant 向量存储一起工作。
## 核心原理解析
Qdrant 的主要功能是在大规模文档库中进行向量相似性搜索。通过使用向量存储,您可以有效地过滤和检索与特定查询相似的文档。`SelfQueryRetriever` 可以根据文档的元数据字段进行自我查询,从而提高检索效率。
## 代码实现演示(重点)
### 创建 Qdrant 向量存储
首先,我们需要创建一个 Qdrant 向量存储,并用一些数据进行初始化。本文示例使用了一组电影摘要文档。
```python
# 安装所需的第三方库
%pip install --upgrade --quiet lark qdrant-client
# 导入相关模块和类
from langchain_community.vectorstores import Qdrant
from langchain_core.documents import Document
from langchain_openai import OpenAIEmbeddings
# 初始化OpenAI的嵌入对象
embeddings = OpenAIEmbeddings()
# 创建文档列表
docs = [
Document(
page_content="A bunch of scientists bring back dinosaurs and mayhem breaks loose",
metadata={"year": 1993, "rating": 7.7, "genre": "science fiction"},
),
Document(
page_content="Leo DiCaprio gets lost in a dream within a dream within a dream within a ...",
metadata={"year": 2010, "director": "Christopher Nolan", "rating": 8.2},
),
Document(
page_content="A psychologist / detective gets lost in a series of dreams within dreams within dreams and Inception reused the idea",
metadata={"year": 2006, "director": "Satoshi Kon", "rating": 8.6},
),
Document(
page_content="A bunch of normal-sized women are supremely wholesome and some men pine after them",
metadata={"year": 2019, "director": "Greta Gerwig", "rating": 8.3},
),
Document(
page_content="Toys come alive and have a blast doing so",
metadata={"year": 1995, "genre": "animated"},
),
Document(
page_content="Three men walk into the Zone, three men walk out of the Zone",
metadata={
"year": 1979,
"rating": 9.9,
"director": "Andrei Tarkovsky",
"genre": "science fiction",
},
),
]
# 在Qdrant中创建向量存储
vectorstore = Qdrant.from_documents(
docs,
embeddings,
location=":memory:", # 本地模式,仅使用内存存储
collection_name="my_documents",
)
创建自查询检索器
接下来,我们将实例化自查询检索器。需要提前提供文档支持的元数据字段和对文档内容的简短描述。
from langchain.chains.query_constructor.base import AttributeInfo
from langchain.retrievers.self_query.base import SelfQueryRetriever
from langchain_openai import OpenAI
# 定义元数据字段信息
metadata_field_info = [
AttributeInfo(
name="genre",
description="The genre of the movie",
type="string or list[string]",
),
AttributeInfo(
name="year",
description="The year the movie was released",
type="integer",
),
AttributeInfo(
name="director",
description="The name of the movie director",
type="string",
),
AttributeInfo(
name="rating", description="A 1-10 rating for the movie", type="float"
),
]
# 文档内容描述
document_content_description = "Brief summary of a movie"
llm = OpenAI(temperature=0)
# 实例化自查询检索器
retriever = SelfQueryRetriever.from_llm(
llm, vectorstore, document_content_description, metadata_field_info, verbose=True
)
测试检索功能
现在我们可以开始实际使用自查询检索器来执行查询。
# 查询关于恐龙的电影
retriever.invoke("What are some movies about dinosaurs")
# 仅指定过滤条件:评分大于8.5的电影
retriever.invoke("I want to watch a movie rated higher than 8.5")
# 结合查询和过滤条件:Greta Gerwig导演的关于女性的电影
retriever.invoke("Has Greta Gerwig directed any movies about women")
# 复杂过滤条件:评分高于8.5的科幻电影
retriever.invoke("What's a highly rated (above 8.5) science fiction film?")
# 使用限制和合成过滤条件:[年在1990-2005之间,并是动画的玩具相关电影]
retriever.invoke(
"What's a movie after 1990 but before 2005 that's all about toys, and preferably is animated"
)
应用场景分析
Qdrant的强大查询能力使其非常适合用于需要快速搜索和过滤大规模文档的场景,例如电影推荐系统、产品搜索引擎以及内容分类等。它可以帮助开发者构建高效率的搜索和推荐系统。
实践建议
- 在部署Qdrant时,可以考虑使用云端存储以支持更大的数据规模。
- 使用自查询检索器时应根据实际需求调整元数据字段与描述,确保检索结果的准确性。
- 对于性能敏感的应用,可以优化嵌入生成与存储以提高检索速度。
如果遇到问题欢迎在评论区交流。
---END---