milvus-logo
LFAI
首页
  • 用户指南

混合搜索

自 Milvus 2.4 版起,我们引入了多向量支持和混合搜索框架,这意味着用户可以在一个集合中引入多个向量场(最多 10 个)。不同列中的这些向量代表数据的不同方面,它们来自不同的嵌入模型或经过不同的处理方法。混合搜索的结果会使用重排策略进行整合,如互易等级融合(RRF)和加权评分。要了解有关重新排名策略的更多信息,请参阅重新排名

这一功能在综合搜索场景中特别有用,例如根据图片、声音、指纹等各种属性识别向量库中最相似的人。

在本教程中,您将学习如何

  • 创建多个AnnSearchRequest 实例,用于不同向量场的相似性搜索;

  • 配置重排策略,对多个AnnSearchRequest 实例的搜索结果进行组合和重排;

  • 使用 hybrid_search()方法执行混合搜索。

本页的代码片段使用PyMilvus ORM 模块与 Milvus 交互。使用新MilvusClient SDK的代码片段将很快发布。

准备工作

在开始混合搜索之前,请确保您有一个包含多个向量字段的集合。目前,Milvus 为每个集合引入了默认的四个向量字段,通过修改proxy.maxVectorFieldNum配置,最多可以扩展到十个。

下面是一个例子,说明如何创建一个名为test_collection 的集合,其中包含两个向量字段filmVectorposterVector ,并在其中插入随机实体。

from pymilvus import connections, Collection, FieldSchema, CollectionSchema, DataType
import random

# Connect to Milvus
connections.connect(
host="10.102.7.3", # Replace with your Milvus server IP
port="19530"
)

# Create schema
fields = [
FieldSchema(name="film_id", dtype=DataType.INT64, is_primary=True),
FieldSchema(name="filmVector", dtype=DataType.FLOAT_VECTOR, dim=5), # Vector field for film vectors
FieldSchema(name="posterVector", dtype=DataType.FLOAT_VECTOR, dim=5)] # Vector field for poster vectors

schema = CollectionSchema(fields=fields,enable_dynamic_field=False)

# Create collection
collection = Collection(name="test_collection", schema=schema)

# Create index for each vector field
index_params = {
"metric_type": "L2",
"index_type": "IVF_FLAT",
"params": {"nlist": 128},
}

collection.create_index("filmVector", index_params)
collection.create_index("posterVector", index_params)

# Generate random entities to insert
entities = []

for _ in range(1000):
# generate random values for each field in the schema
film_id = random.randint(1, 1000)
film_vector = [ random.random() for _ in range(5) ]
poster*vector = [ random.random() for * in range(5) ]

    # create a dictionary for each entity
    entity = {
        "film_id": film_id,
        "filmVector": film_vector,
        "posterVector": poster_vector
    }

    # add the entity to the list
    entities.append(entity)

collection.insert(entities)

步骤 1:创建多个 AnnSearchRequest 实例

混合搜索使用hybrid_search() API 在一次调用中执行多个 ANN 搜索请求。每个AnnSearchRequest 代表对特定向量场的单个搜索请求。

下面的示例创建了两个AnnSearchRequest 实例,用于对两个向量场执行单独的相似性搜索。

from pymilvus import AnnSearchRequest

# Create ANN search request 1 for filmVector
query_filmVector = [[0.8896863042430693, 0.370613100114602, 0.23779315077113428, 0.38227915951132996, 0.5997064603128835]]

search_param_1 = {
"data": query_filmVector, # Query vector
"anns_field": "filmVector", # Vector field name
"param": {
"metric_type": "L2", # This parameter value must be identical to the one used in the collection schema
"params": {"nprobe": 10}
},
"limit": 2 # Number of search results to return in this AnnSearchRequest
}
request_1 = AnnSearchRequest(\*\*search_param_1)

# Create ANN search request 2 for posterVector
query_posterVector = [[0.02550758562349764, 0.006085637357292062, 0.5325251250159071, 0.7676432650114147, 0.5521074424751443]]
search_param_2 = {
"data": query_posterVector, # Query vector
"anns_field": "posterVector", # Vector field name
"param": {
"metric_type": "L2", # This parameter value must be identical to the one used in the collection schema
"params": {"nprobe": 10}
},
"limit": 2 # Number of search results to return in this AnnSearchRequest
}
request_2 = AnnSearchRequest(\*\*search_param_2)

# Store these two requests as a list in `reqs`
reqs = [request_1, request_2]

参数:

  • AnnSearchRequest 对象

    代表 ANN 搜索请求的类。每次混合搜索可包含 1 到 1,024 个ANNSearchRequest 对象。

  • data 列表

    要在单个AnnSearchRequest 中搜索的查询向量。目前,该参数只接受包含单个查询向量的列表,例如[[0.5791814851218929, 0.5792985702614121, 0.8480776460143558, 0.16098005945243, 0.2842979317256803]] 。今后,该参数将扩展到接受多个查询向量。

  • anns_field (字符串)

    在单个AnnSearchRequest 中使用的向量字段名称。

  • param (dict)

    单个AnnSearchRequest 的搜索参数字典。这些搜索参数与单向量搜索参数相同。更多信息,请参阅搜索参数

  • limit (int)

    要包含在单个ANNSearchRequest 中的搜索结果的最大数量。

    该参数只影响单个ANNSearchRequest 中返回的搜索结果数,并不决定hybrid_search 调用的最终返回结果。在混合搜索中,最终结果由来自多个ANNSearchRequest 实例的结果组合和重排决定。

步骤 2:配置重排策略

创建AnnSearchRequest 实例后,配置重新排序策略,对结果进行组合和重新排序。目前有两个选项:WeightedRankerRRFRanker 。有关重新排名策略的更多信息,请参阅重新排名

  • 使用加权评分

    WeightedRanker 用于以指定权重为每个向量场搜索结果分配重要性。如果您将某些向量字段的优先级高于其他向量字段,WeightedRanker(value1, value2, ..., valueN) 可以在合并搜索结果中反映这一点。

    from pymilvus import WeightedRanker
    # Use WeightedRanker to combine results with specified weights
    # Assign weights of 0.8 to text search and 0.2 to image search
    rerank = WeightedRanker(0.8, 0.2)  
    

    使用WeightedRanker 时,请注意

    • 每个权重值的范围从 0(最不重要)到 1(最重要),影响最终的综合得分。
    • WeightedRanker 中提供的权重值总数应等于您创建的AnnSearchRequest 实例数。
  • 使用互惠排名融合(RFF)

    # Alternatively, use RRFRanker for reciprocal rank fusion reranking
    from pymilvus import RRFRanker
    
    rerank = RRFRanker()
    

设置好AnnSearchRequest 实例和重排策略后,使用hybrid_search() 方法执行混合搜索。

# Before conducting hybrid search, load the collection into memory.
collection.load()

res = collection.hybrid_search(
reqs, # List of AnnSearchRequests created in step 1
rerank, # Reranking strategy specified in step 2
limit=2 # Number of final search results to return
)

print(res)

参数:

  • reqs 列表

    搜索请求列表,其中每个请求都是一个ANNSearchRequest 对象。每个请求可以对应一个不同的向量场和一组不同的搜索参数。

  • rerank 对象

    用于混合搜索的重排策略。可能的值:WeightedRanker(value1, value2, ..., valueN)RRFRanker()

    有关重排策略的更多信息,请参阅重排

  • limit (int)

    在混合搜索中返回的最终结果的最大数量。

输出类似于下图:

["['id: 844, distance: 0.006047376897186041, entity: {}', 'id: 876, distance: 0.006422005593776703, entity: {}']"]

限制

  • 通常情况下,每个集合默认最多允许 4 个向量字段。不过,您可以选择调整proxy.maxVectorFieldNum 配置,以扩大集合中向量字段的最大数量,每个集合的最大限制为 10 个向量字段。有关更多信息,请参阅 "代理相关配置"

  • 集合中的部分索引或加载的向量字段将导致错误。

  • 目前,混合搜索中的每个AnnSearchRequest 只能携带一个查询向量。

常见问题

  • 建议在哪些情况下使用混合搜索?

    混合搜索非常适合需要高精确度的复杂情况,尤其是当一个实体可以由多个不同的向量表示时。这适用于同一数据(如一个句子)通过不同的嵌入模型进行处理的情况,或多模态信息(如个人的图像、指纹和声纹)转换成各种向量格式的情况。通过给这些向量分配权重,它们的综合影响可以极大地丰富搜索结果的召回率并提高搜索结果的有效性。

  • 加权排序器如何对不同向量场之间的距离进行归一化处理?

    加权排序器使用为每个字段分配的权重对向量字段之间的距离进行归一化处理。它根据每个向量场的权重计算其重要性,优先考虑权重较高的向量场。建议在 ANN 搜索请求中使用相同的度量类型,以确保一致性。这种方法可确保被认为更重要的向量对整体排名产生更大的影响。

  • 是否可以使用 Cohere Ranker 或 BGE Ranker 等其他排名器?

    目前只支持所提供的排名器。正在计划在未来的更新中加入其他排名器。

  • 是否可以同时执行多个混合搜索操作?

    可以,支持同时执行多个混合搜索操作。

  • 能否在多个 AnnSearchRequest 对象中使用相同的向量字段来执行混合搜索?

    从技术上讲,可以在多个 AnnSearchRequest 对象中使用相同的向量字段进行混合搜索。混合搜索并不需要多个向量字段。

翻译自DeepLogo

反馈

此页对您是否有帮助?