跳到主要内容
版本:v2.5.x

基本向量搜索

近似近邻(ANN)搜索以记录 Embedding 排序顺序的索引文件为基础,根据接收到的搜索请求中携带的查询向量查找 Embedding 子集,将查询向量与子群中的向量进行比较,并返回最相似的结果。通过 ANN 搜索,Milvus 提供了高效的搜索体验。本页将帮助您了解如何进行基本的 ANN 搜索。

概述

ANN 和 k-Nearest Neighbors (kNN) 搜索是向量相似性搜索的常用方法。在 kNN 搜索中,必须将向量空间中的所有向量与搜索请求中携带的查询向量进行比较,然后找出最相似的向量,这既耗时又耗费资源。

与 kNN 搜索不同,ANN 搜索算法要求提供一个索引文件,记录向量 Embedding 的排序顺序。当收到搜索请求时,可以使用索引文件作为参考,快速找到可能包含与查询向量最相似的 Embedding 的子组。然后,你可以使用指定的度量类型来测量查询向量与子组中的向量之间的相似度,根据与查询向量的相似度对组成员进行排序,并找出前 K 个组成员。

ANN 搜索依赖于预建索引,搜索吞吐量、内存使用量和搜索正确性可能会因选择的索引类型而不同。您需要在搜索性能和正确性之间取得平衡。

为了减少学习曲线,Milvus 提供了AUTOINDEX。通过AUTOINDEX,Milvus 可以在建立索引的同时分析 Collection 中的数据分布,并根据分析结果设置最优化的索引参数,从而在搜索性能和正确性之间取得平衡。

在本节中,你将找到有关以下主题的详细信息:

在 ANN 搜索中,单向量搜索指的是只涉及一个查询向量的搜索。根据预建索引和搜索请求中携带的度量类型,Milvus 将找到与查询向量最相似的前 K 个向量。

本节将介绍如何进行单向量搜索。搜索请求携带单个查询向量,要求 Milvus 使用内积(IP)计算查询向量与 Collection 中向量的相似度,并返回三个最相似的向量。

from pymilvus import MilvusClient

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

# 4. Single vector search
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,
search_params={"metric_type": "IP"}
)

for hits in res:
for hit in hits:
print(hit)

# [
# [
# {
# "id": 551,
# "distance": 0.08821295201778412,
# "entity": {}
# },
# {
# "id": 296,
# "distance": 0.0800950899720192,
# "entity": {}
# },
# {
# "id": 43,
# "distance": 0.07794742286205292,
# "entity": {}
# }
# ]
# ]

Milvus 根据搜索结果与查询向量的相似度得分从高到低排列搜索结果。相似度得分也称为与查询向量的距离,其数值范围随使用的度量类型而变化。

下表列出了适用的度量类型和相应的距离范围。

| 度量类型

|

特征

|

距离范围

| | --- | --- | --- | |

L2

|

值越小表示相似度越高。

|

[0, ∞)

| |

IP

|

数值越大,表示相似度越高。

|

[-1, 1]

| |

COSINE

|

数值越大,表示相似度越高。

|

[-1, 1]

| |

JACCARD

|

值越小,表示相似度越高。

|

[0, 1]

| |

HAMMING

|

值越小,表示相似度越高。

|

[0,dim(向量)] 批量向量搜索

|

同样,您也可以在一个搜索请求中包含多个查询向量。Milvus 将并行对查询向量进行 ANN 搜索,并返回两组结果。

# 7. Search with multiple vectors
# 7.1. Prepare query vectors
query_vectors = [
[0.041732933, 0.013779674, -0.027564144, -0.013061441, 0.009748648],
[0.0039737443, 0.003020432, -0.0006188639, 0.03913546, -0.00089768134]
]

# 7.2. Start search
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)

# Output
#
# [
# [
# {
# "id": 551,
# "distance": 0.08821295201778412,
# "entity": {}
# },
# {
# "id": 296,
# "distance": 0.0800950899720192,
# "entity": {}
# },
# {
# "id": 43,
# "distance": 0.07794742286205292,
# "entity": {}
# }
# ],
# [
# {
# "id": 730,
# "distance": 0.04431751370429993,
# "entity": {}
# },
# {
# "id": 333,
# "distance": 0.04231833666563034,
# "entity": {}
# },
# {
# "id": 232,
# "distance": 0.04221535101532936,
# "entity": {}
# }
# ]
# ]

在 Partition 中进行 ANN 搜索

假设您在一个 Collection 中创建了多个 Partition,您可以将搜索范围缩小到特定数量的 Partition。在这种情况下,您可以在搜索请求中包含目标 Partition 名称,将搜索范围限制在指定的 Partition 内。减少搜索所涉及的 Partition 数量可以提高搜索性能。

下面的代码片段假定 Collection 中有一个名为PartitionA的 Partition。

# 4. Single vector search
query_vector = [0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592]
res = client.search(
collection_name="quick_setup",
partition_names=["partitionA"],
data=[query_vector],
limit=3,
)

for hits in res:
print("TopK results:")
for hit in hits:
print(hit)

# [
# [
# {
# "id": 551,
# "distance": 0.08821295201778412,
# "entity": {}
# },
# {
# "id": 296,
# "distance": 0.0800950899720192,
# "entity": {}
# },
# {
# "id": 43,
# "distance": 0.07794742286205292,
# "entity": {}
# }
# ]
# ]

使用输出字段

在搜索结果中,Milvus 默认会包含包含 TOP-K Embedding 的实体的主字段值和相似度距离/分数。您可以在搜索请求中包含目标字段(包括向量和标量字段)的名称作为输出字段,使搜索结果携带这些实体中其他字段的值。

# 4. Single vector search
query_vector = [0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592],

res = client.search(
collection_name="quick_setup",
data=[query_vector],
limit=3, # The number of results to return
search_params={"metric_type": "IP"}
output_fields=["color"]
)

print(res)

# [
# [
# {
# "id": 551,
# "distance": 0.08821295201778412,
# "entity": {
# "color": "orange_6781"
# }
# },
# {
# "id": 296,
# "distance": 0.0800950899720192,
# "entity": {
# "color": "red_4794"
# }
# },
# {
# "id": 43,
# "distance": 0.07794742286205292,
# "entity": {
# "color": "grey_8510"
# }
# }
# ]
# ]

使用限制和偏移

您可能会注意到,搜索请求中包含的参数limit 决定了搜索结果中包含的实体数量。该参数指定了单次搜索中返回实体的最大数量,通常称为top-K。

如果希望执行分页查询,可以使用循环来发送多个搜索请求,每个查询请求中都包含LimitOffset参数。具体来说,可以将 "**限制 "**参数设置为希望包含在当前查询结果中的实体数量,将 "偏移"参数设置为已经返回的实体总数。

下表概述了在一次返回 100 个 "实体 "时,如何为分页查询设置 "限制"和**"偏移**"参数。

| 查询

|

每次查询要返回的实体

|

已返回实体总数

| | --- | --- | --- | |

第 1 次查询

|

100

|

0

| |

第二次查询

|

100

|

100

| |

第三次查询

|

100

|

200

| |

第 n 次查询

|

100

|

100 x (n-1)

|

请注意,在一次 ANN 搜索中,limitoffset 的总和应小于 16 384。

# 4. Single vector search
query_vector = [0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592],

res = client.search(
collection_name="quick_setup",
data=[query_vector],
limit=3, # The number of results to return
search_params={
"metric_type": "IP",
"offset": 10 # The records to skip
}
)

AUTOINDEX 可大大拉平 ANN 搜索的学习曲线。然而,随着 Top-K 的增加,搜索结果不一定总是正确的。通过缩小搜索范围、提高搜索结果相关性和搜索结果多样化,Milvus 实现了以下搜索增强功能。

  • 过滤搜索

    您可以在搜索请求中包含过滤条件,这样 Milvus 就会在进行 ANN 搜索前进行元数据过滤,将搜索范围从整个 Collection 缩小到只搜索符合指定过滤条件的实体。

    有关元数据过滤和过滤条件的更多信息,请参阅过滤搜索过滤解释和相关主题。

  • 范围搜索

    您可以在特定范围内限制返回实体的距离或得分,从而提高搜索结果的相关性。在 Milvus 中,范围搜索包括以与查询向量最相似的 Embedding 向量为中心,画两个同心圆。搜索请求指定了两个圆的半径,Milvus 会返回所有属于外圆但不属于内圆的 Embedding。

    有关范围搜索的更多信息,请参阅范围搜索

  • 分组搜索

    如果返回的实体在特定字段中持有相同的值,搜索结果可能无法代表向量空间中所有 Embedding 的分布情况。要使搜索结果多样化,可以考虑使用分组搜索。

    有关分组搜索的更多信息,请参阅分组搜索

  • 混合搜索

    一个 Collection 最多可以包含四个向量字段,以保存使用不同 Embedding 模型生成的 Embedding。通过这种方式,可以使用混合搜索对这些向量字段的搜索结果进行 Reranker,从而提高召回率。

    有关混合搜索的更多信息,请参阅混合搜索

  • 搜索迭代器

    单个 ANN 搜索最多可返回 16,384 个实体。如果需要在单次搜索中返回更多实体,请考虑使用搜索迭代器。

    有关搜索迭代器的详细信息,请参阅搜索迭代器

  • 全文搜索

    全文搜索是一种在文本数据集中检索包含特定术语或短语的文档,然后根据相关性对结果进行排序的功能。该功能克服了语义搜索的局限性(语义搜索可能会忽略精确的术语),确保您获得最准确且与上下文最相关的结果。此外,它还能接受原始文本输入,自动将文本数据转换为稀疏嵌入,无需手动生成 Embedding,从而简化了向量搜索。

    有关全文搜索的详细信息,请参阅全文搜索

  • 关键词匹配

    Milvus 的关键词匹配功能可根据特定术语精确检索文档。该功能主要用于满足特定条件的过滤搜索,并可结合标量过滤来完善查询结果,允许在符合标量标准的向量内进行相似性搜索。

    有关关键字匹配的详细信息,请参阅关键字匹配

  • 使用 Partition Key

    在元数据过滤中涉及多个标量字段并使用相当复杂的过滤条件可能会影响搜索效率。一旦将一个标量字段设置为 Partition 关键字,并在搜索请求中使用涉及 Partition 关键字的过滤条件,就可以帮助将搜索范围限制在与指定 Partition 关键字值相对应的 Partition 内。

    有关 Partition Key 的详细信息,请参阅使用 Partition Key

  • 使用 mmap

    有关 mmap 设置的详情,请参阅使用 mmap

  • 聚类压缩

    有关聚类压缩的详情,请参阅聚类压缩。