处理大规模向量数据时,我们常常会面临这样的问题:如何高效地进行向量相似性搜索?Milvus 作为一款专业的向量数据库,提供了丰富的搜索功能来应对这一挑战。今天,咱们就来深入聊聊 Milvus 的向量搜索,从基础操作到高级技巧,帮你全面掌握其中的核心逻辑。

一、基本向量搜索:开启高效检索之旅

在 Milvus 中,近似近邻(ANN)搜索是向量相似性搜索的常用方法,它依赖于预建索引,能在保证一定精度的前提下,大幅提升搜索效率。咱们先从基本的单向量搜索和批量向量搜索说起。

1. 单向量搜索:精准定位单个查询向量的相似结果

单向量搜索,就是针对一个查询向量,找到与之最相似的前 K 个向量。咱们来看一个具体的代码示例:

python

运行

from pymilvus import MilvusClient

client = MilvusClient(
    uri="http://localhost:19530",
    token="root:Milvus"
)

# 定义查询向量
query_vector = [0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592]

# 执行搜索
res = client.search(
    collection_name="quick_setup",  # 集合名称
    anns_field="vector",  # 向量字段名
    data=[query_vector],  # 查询向量数据
    limit=3,  # 返回前3个结果
    search_params={"metric_type": "IP"}  # 度量类型为内积
)

# 输出结果
for hits in res:
    for hit in hits:
        print(hit)

在这个示例中,collection_name指定了要搜索的集合,anns_field是存储向量数据的字段名,data是查询向量,limit设置了返回结果的数量,search_params中的metric_type指定了计算相似度的度量类型。不同的度量类型有不同的距离范围和含义,比如 L2 距离越小相似度越高,IP 值越大相似度越高,这些都需要根据实际需求来选择。

2. 批量向量搜索:一次处理多个查询向量

当我们有多个查询向量时,就可以使用批量向量搜索,Milvus 会并行处理这些查询,提高效率。代码如下:

python

运行

# 准备多个查询向量
query_vectors = [
    [0.041732933, 0.013779674, -0.027564144, -0.013061441, 0.009748648],
    [0.0039737443, 0.003020432, -0.0006188639, 0.03913546, -0.00089768134]
]

# 执行批量搜索
res = client.search(
    collection_name="quick_setup",
    data=query_vectors,
    limit=3,
)

# 输出结果
for hits in res:
    print("TopK results:")
    for hit in hits:
        print(hit)

3. 分区中的搜索:缩小范围提升性能

如果集合中创建了多个分区,我们可以将搜索范围限定在特定分区内,减少搜索的数据量,从而提高性能。只需在搜索请求中添加partition_names参数即可:

python

运行

# 指定分区名称进行搜索
res = client.search(
    collection_name="quick_setup",
    partition_names=["partitionA"],  # 目标分区名称
    data=[query_vector],
    limit=3,
)

4. 输出字段:获取更多实体信息

默认情况下,搜索结果包含实体的 ID、距离和空的实体数据。如果我们想获取实体中其他字段的值,比如标量字段,可以通过output_fields参数指定:

python

运行

# 指定输出字段
res = client.search(
    collection_name="quick_setup",
    data=[query_vector],
    limit=3,
    search_params={"metric_type": "IP"},
    output_fields=["color"]  # 要输出的字段名
)

5. 限制和偏移:实现分页查询

当数据量较大时,我们可以使用limitoffset参数进行分页查询。limit指定每次返回的实体数量,offset指定跳过的记录数。需要注意的是,两者的总和应小于 16384。

二、增强 ANN 搜索:满足多样化搜索需求

除了基本搜索功能,Milvus 还提供了多种增强的 ANN 搜索功能,来应对更复杂的搜索场景。

1. 过滤搜索:缩小搜索范围提高相关性

过滤搜索可以在 ANN 搜索前对元数据进行过滤,只在符合条件的实体内进行搜索。过滤条件可以是多个条件的组合,比如color like "red%" and likes > 50。过滤搜索分为标准过滤和迭代过滤:

  • 标准过滤:适用于过滤条件不太复杂的情况,能有效缩小搜索范围。
  • 迭代过滤:当过滤表达式过于复杂导致延迟较高时使用,通过迭代方式逐个处理实体,减少标量过滤的工作量。

python

运行

# 标准过滤搜索示例
res = client.search(
    collection_name="my_collection",
    data=[query_vector],
    limit=5,
    filter='color like "red%" and likes > 50',  # 过滤条件
    output_fields=["color", "likes"]
)

2. 范围搜索:按距离范围筛选结果

范围搜索可以将返回实体的距离或得分限制在特定范围内,提高搜索结果的相关性。不同的度量类型设置半径和范围过滤的方式不同,比如对于 COSINE 度量类型,要确保半径值小于范围过滤值。

python

运行

# 范围搜索示例
res = client.search(
    collection_name="my_collection",
    data=[query_vector],
    limit=3,
    search_params={
        "params": {
            "radius": 0.4,  # 外圈半径
            "range_filter": 0.6  # 内圈半径
        }
    }
)

3. 分组搜索:提高搜索结果多样性

当搜索结果中存在同一文档的多个段落等情况时,分组搜索可以按指定字段对结果进行分组,从每个组中返回最相似的实体,提高结果的多样性。通过group_by_field指定分组字段,group_sizestrict_group_size控制每组返回的实体数量。

python

运行

# 分组搜索示例
res = client.search(
    collection_name="my_collection",
    data=query_vectors,
    limit=3,
    group_by_field="docId",  # 分组字段
    output_fields=["docId"]
)

4. 混合搜索:结合多个向量场提升准确性

如果集合中包含多个向量场,比如使用不同嵌入模型生成的密集向量和稀疏向量,混合搜索可以对这些向量场的搜索结果进行重排,提高召回率。Milvus 支持加权排名(WeightedRanker)和互易排名融合(RRFRanker)两种重排策略:

  • 加权排名:为不同向量场分配不同权重,强调特定向量场的重要性。
  • RRFRanker:平衡不同向量场的重要性,适用于没有特定重点的场景。

python

运行

# 加权排名示例
from pymilvus import WeightedRanker

ranker = WeightedRanker(0.8, 0.3)  # 为两个向量场分配权重
res = client.hybrid_search(
    collection_name="my_collection",
    reqs=reqs,  # 多个AnnSearchRequest实例
    ranker=ranker,
    limit=2
)

三、其他实用功能:应对特殊搜索场景

1. 全文搜索:简化文本搜索流程

全文搜索无需手动生成向量嵌入,直接接受原始文本输入,自动转换为稀疏嵌入,使用 BM25 算法进行相关性评分。适用于检索增强生成(RAG)等场景,能优先处理与搜索词密切匹配的文档。

2. 文本匹配:精确检索包含特定术语的文档

文本匹配基于倒排索引,对输入文本进行标记化处理,快速检索包含指定术语的文档。可以结合标量过滤进一步细化查询结果。

3. 搜索迭代器:处理大规模检索需求

当单次搜索需要返回的实体数量超过 16384 时,使用搜索迭代器以分页方式获取结果,提高处理大规模数据的能力。

4. 分区密钥:优化分区搜索效率

将标量字段设置为分区密钥后,Milvus 会根据分区密钥值将实体存储到相应分区,搜索时通过过滤条件限制在特定分区内,提高搜索效率。启用分区密钥隔离功能(适用于 HNSW 索引)还能为每个分区密钥值分组创建单独索引,进一步提升性能。

总结:灵活运用,找到最优解

Milvus 的向量搜索功能丰富多样,从基本的单向量搜索到高级的混合搜索,从过滤搜索到全文搜索,每个功能都有其适用场景。我们需要根据数据特点、查询需求和性能要求,灵活选择合适的搜索方法和参数。

希望这篇文章能帮助你更好地理解和使用 Milvus 的向量搜索功能。如果你觉得有用,别忘了关注、收藏和点赞,后续我们还会带来更多关于 Milvus 和向量数据库的实用知识!

Logo

中国智能体开发者社区,聚焦智能体与大模型开发,提供前沿资讯、实用工具链、开源项目及行业案例。通过技术沙龙、开发者大赛等活动,促进经验交流与协作,助力开发者快速构建创新智能应用。

更多推荐