近似近邻检索和过滤搜索
本节介绍两种检索方式的核心概念和区别。
核心概念
| 检索方式 | 核心特点 | 适用场景 |
|---|---|---|
| 近似近邻检索(ANN) | 基于向量嵌入的语义相似度匹配 | 理解含义和上下文 |
| 全文检索(BM25) | 基于关键词的精确匹配 | 特定术语、关键词搜索 |
| 过滤检索 | 基于元数据的条件筛选 | 按类别、日期等过滤 |
一句话总结:ANN 找"意思相近"的,BM25 找"包含关键词"的。
近似近邻检索(ANN)
基于向量嵌入的相似度匹配,找出"意思相近"的文档。
原理:将查询文本通过 嵌入模型转换为向量,然后在向量空间中找出与查询向量最相似的文档。
特点:
- 需要预先将文档转换为向量(密集嵌入)
- 擅长语义理解,如"如何清洁半导体"能匹配到"等离子体清洗技术"
- 可以通过调整返回结果数量(k值)控制召回率
过滤检索
使用 Milvus 标量过滤规则,根据元数据(如 category、filename 等)筛选文档。
原理:在 ANN 搜索之前,先根据元数据条件过滤掉不相关的文档,缩小搜索范围。
应用场景:
- 只检索某个分类下的文档(如 category == "Title")
- 只检索特定文件的文档
- 按时间范围筛选
Milvus 支持以下几种用于过滤数据的基本操作符:
| 类型 | 操作符 | 说明 |
|---|---|---|
| 比较操作符 | ==, !=, >, <, >=, <= | 基于数字、文本或日期字段筛选 |
| 范围过滤器 | IN, LIKE | 匹配特定的值范围或集合 |
| 算术操作符 | +, -, *, /, % | 涉及数字字段的计算 |
| 逻辑操作符 | AND, OR, NOT / &&, ||, ! | 组合多个条件 |
示例:
filter = "age > 25 and city in ['北京', '上海']"
二者结合检索
如果 Collections 同时包含向量嵌入及其元数据,您可以在 ANN 搜索之前过滤元数据,以提高搜索结果的相关性。Milvus 收到携带过滤条件的搜索请求后,会将搜索范围限制在符合指定过滤条件的实体内。
如上图所示,搜索请求携带 chunk like % red % 作为过滤条件,表明 Milvus 应在 chunk 字段中包含 red 的所有实体内进行 ANN 搜索。具体来说,Milvus 会执行以下操作。
- 过滤符合搜索请求中过滤条件的实体。
- 在过滤后的实体中进行 ANN 搜索。
- 返回前 K 个实体。
代码示例
近似近邻检索
from document.milvus_db import MilvusVectorSave
if __name__ == '__main__':
mv = MilvusVectorSave()
mv.create_connection(is_first=False)
# 近似近邻检索(不带分数)
result = mv.vector_store_saved.similarity_search(
query='现在,最先进的纳米清洗技术是什么?',
k=2 # 返回2条结果
)
for doc in result:
print(doc)
近似近邻检索(带分数)
# 近似近邻检索(带相似度分数)
result = mv.vector_store_saved.similarity_search_with_score(
query='现在,最先进的纳米清洗技术是什么?',
k=2
)
for doc, score in result:
print(f"内容: {doc.page_content[:50]}...")
print(f"分数: {score}")
过滤检索
# 过滤检索:根据 category 元数据过滤
result = mv.vector_store_saved.similarity_search_with_score(
query='现在,最先进的纳米清洗技术是什么?',
k=2,
expr='category == "Title"' # 只检索 category 为 Title 的文档
)
for doc, score in result:
print(doc)
常用过滤条件
| 过滤条件 | 说明 |
|---|---|
category == "Title" | 只检索标题类文档 |
category == "content" | 只检索正文类文档 |
filename == "tech_report.md" | 只检索指定文件 |
category in ["Title", "content"] | 检索标题和正文 |
返回结果示例
(Document(
page_content='半导体制造中的纳米级污染物清洁工艺 -> 面向先进节点的创新工艺',
metadata={'category': 'Title', 'filename': 'tech_report_froo52ed.md', ...}
), 0.6518062353134155)
(Document(
page_content='半导体制造中的纳米级污染物清洁工艺',
metadata={'category': 'Title', 'filename': 'tech_report_froo52ed.md', ...}
), 0.6353697776794434)
参数说明
| 参数 | 说明 |
|---|---|
query | 查询字符串 |
k | 返回结果数量,相当于 topK |
expr | 过滤表达式 |
score | 相似度分数,越高表示越相似 |