一架梯子,一头程序猿,仰望星空!
Milvus向量数据库教程 > 内容正文

Go Milvus相似搜索


向量相似性搜索

本主题介绍如何在Milvus中进行实体搜索。

Milvus中的向量相似性搜索计算查询向量与集合中向量之间的距离,并返回最相似的结果。您可以通过指定布尔表达式来执行混合搜索,该表达式用于过滤标量字段或主键字段。

以下示例演示了如何对包含2000行数据集的图书ID(主键)、词频(标量字段)和图书介绍(向量字段)执行向量相似性搜索,以模拟根据向量化介绍搜索特定图书的情况。Milvus将根据您定义的查询向量和搜索参数返回最相似的结果。

加载集合

在执行向量相似性搜索之前,Milvus会将所有搜索和查询操作在内存中执行。在进行向量相似性搜索之前,请将集合加载到内存中。

err := milvusClient.LoadCollection(
  context.Background(),   // ctx
  "book",                 // CollectionName
  false                   // async
)
if err != nil {
  log.Fatal("failed to load collection:", err.Error())
}

准备搜索参数

准备适用于您的搜索场景的参数。以下示例定义了使用欧几里德距离计算距离,并从由IVF_FLAT索引构建的十个最近聚类中检索向量的搜索。

sp, _ := entity.NewIndexIvfFlatSearchParam( // NewIndex*SearchParam func
    10,                                  // searchParam
)

opt := client.SearchQueryOptionFunc(func(option *client.SearchQueryOption) {
    option.Limit = 3
    option.Offset = 0
    option.ConsistencyLevel = entity.ClStrong
    option.IgnoreGrowing = false
})
参数 描述 选项
NewIndex*SearchParam func 根据不同的索引类型创建entity.SearchParam的函数。 对于浮点向量:- NewIndexFlatSearchParam() (FLAT) - NewIndexIvfFlatSearchParam(nprobe int) (IVF_FLAT) - NewIndexIvfSQ8SearchParam(nprobe int) (IVF_SQ8) - NewIndexIvfPQSearchParam(nprobe int) (RNSG) - NewIndexHNSWSearchParam(ef int) (HNSW) 对于二进制向量:- NewIndexBinFlatSearchParam(nprobe int) (BIN_FLAT) - NewIndexBinIvfFlatSearchParam(nprobe int) (BIN_IVF_FLAT)
sp 由前面函数返回的索引特定的搜索参数。 有关详细信息,请参见向量索引。
opt ANN搜索的选项。 - Limit:指定要返回的实体数。 - Offset:指定搜索期间要跳过的实体数。此参数和Limit的总和应小于16384。例如,如果您希望查询向量的第9和第10个最近邻居,将Limit设置为2Offset设置为8。 - ConsistencyLevel:指定搜索期间应用的一致性级别。 - Ignore Growing:指示是否在相似性搜索中忽略正在增长的分段。默认值为False,表示搜索涉及正在增长的分段。

执行向量搜索

使用 Milvus 进行向量搜索。要在特定分区中进行搜索,请指定分区名称列表。

Milvus 支持为搜索设置一致性级别。本主题中的示例将一致性级别设置为Strong。您还可以将一致性级别设置为BoundedSessionEventually。有关 Milvus 中四个一致性级别的更多信息,请参见一致性。

searchResult, err := milvusClient.Search(
    context.Background(),                    // ctx
    "book",                                  // CollectionName
    []string{},                              // partitionNames
    "",                                      // expr
    []string{"book_id"},                     // outputFields
    []entity.Vector{entity.FloatVector([]float32{0.1, 0.2})}, // vectors
    "book_intro",                            // vectorField
    entity.L2,                               // metricType
    10,                                      // topK
    sp,                                      // sp
    opt,
)
if err != nil {
    log.Fatal("搜索集合失败:", err.Error())
}
参数 描述 选项
ctx 用于控制 API 调用过程的上下文
CollectionName 要加载的集合名称
partitionNames 要加载的分区名称列表。如果为空,则搜索所有分区
expr 用于筛选属性的布尔表达式 有关详细信息,请参见布尔表达式规则
output_fields 要返回的字段名称
vectors 要搜索的向量
vectorField 要进行搜索的字段名称
metricType 用于搜索的度量类型 此参数必须与用于构建索引的度量类型相同
topK 要返回的结果数量。此值与opts中的offset的和应小于16384
sp 应特定于索引的entity.SearchParam N/A

检查最相似向量的主键值和距离。

fmt.Printf("%#v\n", searchResult)
for _, sr := range searchResult {
    fmt.Println(sr.IDs)
    fmt.Println(sr.Scores)
}

在搜索完成后,释放在 Milvus 中加载的集合,以减少内存消耗。

err := milvusClient.ReleaseCollection(
    context.Background(),                            // ctx
    "book",                                          // CollectionName
)
if err != nil {
    log.Fatal("释放集合失败:", err.Error())
}

限制

功能 最大限制
集合名称的长度 255 个字符
集合中的分区数 4,096
集合中的字段数 256
集合中的分片数 256
向量的维数 32,768
Top K 16,384
目标输入向量数 16,384

进行混合搜索

混合搜索实质上是带有属性过滤的向量搜索。通过指定过滤标量字段或主键字段的布尔表达式,可以根据特定条件限制搜索。

下面的示例展示了如何在常规向量搜索的基础上执行混合搜索。假设您想根据书籍的向量化介绍搜索特定的书籍,但您只想获取在特定字数范围内的书籍。然后,您可以通过在搜索参数中指定布尔表达式来筛选word_count字段。Milvus将仅在与表达式匹配的实体中搜索相似向量。

sp, _ := entity.NewIndexFlatSearchParam(   // NewIndex*SearchParam func
  10,                                      // searchParam
)

opt := client.SearchQueryOptionFunc(func(option *client.SearchQueryOption) {
    option.Limit = 3
    option.Offset = 0
    option.ConsistencyLevel = entity.ClStrong
    option.IgnoreGrowing = false
})

searchResult, err := milvusClient.Search(
  context.Background(),                    // ctx
  "book",                                  // CollectionName
  []string{},                              // partitionNames
  "word_count <= 11000",                   // expr
  []string{"book_id"},                     // outputFields
  []entity.Vector{entity.FloatVector([]float32{0.1, 0.2})}, // vectors
  "book_intro",                            // vectorField
  entity.L2,                               // metricType
  2,                                       // topK
  sp,                                      // sp
  opt,                                     // search options
)

if err != nil {
  log.Fatal("搜索集合失败:", err.Error())
}

检查返回的结果。

fmt.Printf("%#v\n", searchResult)
for _, sr := range searchResult {
  fmt.Println(sr.IDs)
  fmt.Println(sr.Scores)
}


关联主题