Decay Ranker 概述公测版
在传统的向量搜索中,结果纯粹是按照向量相似度来排序的,即向量在数学空间中的匹配程度。但在实际应用中,使内容真正相关的因素往往不仅仅取决于语义相似度。
思考一下这些日常场景:
- 
一个新闻搜索,其中昨天的文章应该比三年前的类似文章排名更高
 - 
一款餐厅查找器,优先推荐距离5分钟路程的场所,而非需要30分钟车程的场所
 - 
一个电子商务平台,即使热门产品与搜索查询的相似度略低,也能提升其热度
 
这些场景都有一个共同的需求:平衡向量相似度与其他数值因素,如时间、距离或受欢迎程度。
Zilliz Cloud 中的 Decay Ranker 通过根据数字类型字段的值调整搜索排名来满足这一需求。它们使您能够在向量相似度与数据的“新鲜度”、“接近度”或其他数值属性之间取得平衡,从而创造出更直观、与上下文相关的搜索体验。
使用说明
- 
Decay Ranker 不能用于 Grouping Search。
 - 
Decay Ranker 中引用的字段必须为数字类型(
INT8、INT16、INT32、INT64、FLOAT或DOUBLE)。 - 
每个 Decay Ranker 只能使用一个数字类型的字段。
 - 
时间单位一致性:使用基于时间的 Decay Ranker 时,
origin、scale和offset等参数的单位必须与集合数据中使用的单位相匹配:- 
如果您的集合以秒为单位存储时间戳,请对所有参数使用秒
 - 
如果您的集合以毫秒为单位存储时间戳,请对所有参数使用毫秒
 - 
如果您的集合以微秒为单位存储时间戳,请对所有参数使用微秒
 
 - 
 
工作原理
Decay Ranker 通过将时间或地理距离等数值因素纳入排序过程,增强了传统向量搜索。整个过程遵循以下阶段:
阶段1:计算归一化相似度得分
首先,Zilliz Cloud 计算并归一化向量相似度得分,以确保比较的一致性:
- 
对于 L2 和 JACCARD 等基于距离的相似性度量类型(其中值越低表示相似度越高):
normalized_score = 1.0 - (2 × arctan(score))/π这将距离转换为 0 到 1 之间的相似度得分,得分越高越好。
 - 
对于 IP、COSINE 和 BM25 等基于得分的相似性度量类型(其中较高的分数已经表示更好的匹配):分数直接使用,不进行归一化处理。
 
阶段2:计算衰减分数
接下来,Zilliz Cloud 会使用您选择的 Decay Ranker,根据指定的数字段的值(如时间戳或距离)计算衰减分数:
- 
每个 Decay Ranker 将原始数值转换为 0 到 1 之间的归一化相关性得分
 - 
衰减得分表示一个项目基于其与理想点的“距离”的相关性
 
具体的计算公式因 Decay Ranker 类型而异。有关如何计算衰减分数的详细信息,请参考高斯衰减、指数衰减、线性衰减。
阶段3:计算最终得分
最后,Zilliz Cloud 将归一化相似度得分和衰减得分相结合,得出最终排名得分:
final_score = normalized_similarity_score × decay_score
在混合搜索(结合多个向量字段)的情况下,Zilliz Cloud 会采用搜索请求中的最大归一化相似度得分:
final_score = max([normalized_score₁, normalized_score₂, ..., normalized_scoreₙ]) × decay_score
例如,在混合搜索中,如果一篇研究论文的向量相似度评分为 0.82,基于 BM25 的文本检索评分为0.91,Zilliz Cloud 在应用衰减因子之前会使用0.91作为基础相似度评分。
使用 Decay Ranker
让我们来看一个在实际场景中使用 Decay Ranker 的示例——以基于时间的衰减来搜索**"AI research papers"**:
在这个示例中,衰减分数反映了相关性如何随时间减弱——较新的论文得分更接近1.0,较旧的论文得分较低。这些值是使用特定的 Decay Ranker 计算得出的。有关详细信息,请参阅选择合适的 Decay Ranker。
论文  | 向量相似度  | 归一化相似度得分  | 出版日期  | 衰减得分  | 最终得分  | 最终排名  | 
|---|---|---|---|---|---|---|
论文 A  | 高  | 0.85 (  | 两周前  | 0.80  | 0.68  | 2 | 
论文 B  | 非常高  | 0.92 (  | 6个月前  | 0.45  | 0.41  | 3 | 
论文 C  | 中等  | 0.75 (  | 1天前  | 0.98  | 0.74  | 1 | 
文件 D  | 中高  | 0.76 (  | 3周前  | 0.70  | 0.53  | 4 | 
如果不使用 Decay Ranker,论文 B 将基于纯向量相似度(0.92)排名最高。然而,应用 Decay Ranker 后:
- 
论文 C 尽管相似度中等,但因其非常新(昨天发表)而跃升至第 1 位
 - 
论文 B 尽管相似度极高,但由于相对较旧,仍降至第 3 位
 - 
论文 D 使用L2距离(数值越低越好),因此在应用衰减之前,其得分从 1.2 归一化为 0.76
 
选择合适的 Decay Ranker
Milvus提供了不同的 Decay Ranker - 高斯(gauss)、指数(exp)、线性(linear),每个 Ranker 都针对特定用例设计:
衰减排序器  | 特性  | 理想用例  | 示例场景  | 
|---|---|---|---|
高斯(  | 自然的、适度延伸的渐进式衰退  | 
  | 在餐厅搜索中,距离3公里的优质场所仍可被发现,不过排名会低于附近的选项  | 
指数(  | 起初迅速下降,但保持长尾  | 
  | 在新闻应用中,昨天的报道排名远高于一周前的内容,但高度相关的旧文章仍可能出现  | 
线性(  | 有明确界限的一致、可预测的下降  | 
  | 在活动查找器中,超过两周未来时间范围的活动根本不会显示  | 
有关每个 Decay Ranker 如何计算分数以及具体衰减模式的详细信息,请参考相关文档:
实施示例
Decay Ranker 可应用于 Zilliz Cloud 中的标准向量搜索和混合搜索操作。以下是实现此功能的关键代码片段。
在使用 Decay Ranker 之前,你必须首先创建一个包含适当数字类型字段(如时间戳、距离等)的集合,这些字段将用于衰减计算。有关包括 Collection 设置、 Schema 定义和数据插入的完整工作示例,请参考教程:实现基于时间的搜索结果重排。
创建一个衰减排序器
要实现衰减排序,首先定义一个 Function 对象,并进行适当的配置:
- Python
 - Java
 - NodeJS
 - Go
 - cURL
 
from pymilvus import Function, FunctionType
# Create a decay function for timestamp-based decay
# Note: All time parameters must use the same unit as your collection data
decay_ranker = Function(
    name="time_decay",                  # Function identifier
    input_field_names=["timestamp"],    # Numeric field to use for decay
    function_type=FunctionType.RERANK,  # Must be set to RERANK for decay rankers
    params={
        "reranker": "decay",            # Specify decay reranker. Must be "decay"
        "function": "gauss",            # Choose decay function type: "gauss", "exp", or "linear"
        "origin": int(datetime.datetime(2025, 1, 15).timestamp()),    # Reference point (seconds)
        "scale": 7 * 24 * 60 * 60,      # 7 days in seconds (must match collection data unit)
        "offset": 24 * 60 * 60,         # 1 day no-decay zone (must match collection data unit)
        "decay": 0.5                    # Half score at scale distance
    }
)
// java
// nodejs
// go
# restful
参数  | 是否必需?  | 描述  | 值/示例  | 
|---|---|---|---|
  | 是  | 执行搜索时使用的函数标识符。选择一个与你的用例相关的描述性名称。  | 
  | 
  | 是  | 用于衰减分数计算的数字字段名称列表。确定将使用数据集的哪个属性来计算衰减(例如,基于时间的衰减使用时间戳,基于位置的衰减使用坐标)。 必须是 Collection 中包含相关数值的字段。支持INT8/16/32/64、FLOAT、DOUBLE。  | 
  | 
  | 是  | 指定正在创建的函数类型。 所有 Decay Ranker 都必须设置为   | 
  | 
  | 是  | 指定要使用的重排序方法。 必须设置为  | 
  | 
  | 是  | 指定要应用的 Decay Ranker 类型。确定相关性下降的曲线形状。 请参阅选择合适的 Decay Ranker 部分,以获取相关指导。  | 
  | 
  | 是  | 计算衰减分数的参考点。处于该值的项目将获得最大相关性分数。 对于基于时间的衰减,时间单位必须与您的集合数据相匹配。  | 
  | 
  | 是  | 相关性降至  对于基于时间的衰减,时间单位必须与您的 Collection 中的数据相匹配。 较大的值会使相关性下降更为平缓;较小的值则会使相关性下降更为陡峭。  | 
  | 
  | 否  | 在  对于基于时间的衰减,时间单位必须与您的 Collection 中的数据相匹配。 在   | 
  | 
  | 否  | 在  必须介于 0 和 1 之间。  | 
  | 
在标准向量搜索中使用
定义 Decay Ranker 后,您可以在搜索请求中通过将其传递给 ranker 参数来应用它:
- Python
 - Java
 - NodeJS
 - Go
 - cURL
 
# Use the decay function in standard vector search
results = milvus_client.search(
    collection_name,
    data=["search query"],
    anns_field="vector_field",
    limit=10,
    output_fields=["document", "timestamp"],  # Include the decay field in outputs to see values
    #  highlight-next-line
    ranker=decay_ranker,                      # Apply the decay ranker here
    consistency_level="Strong"
)
// java
// nodejs
// go
# restful
在混合搜索中使用
衰减排序器也可应用于结合多个向量字段的混合搜索操作:
- Python
 - Java
 - NodeJS
 - Go
 - cURL
 
from pymilvus import AnnSearchRequest
# Define search requests for different vector fields
dense_request = AnnSearchRequest(
    data=["search query"],
    anns_field="dense_vector",
    param={},
    limit=20
)
sparse_request = AnnSearchRequest(
    data=["search query"],
    anns_field="sparse_vector",
    param={},
    limit=20
)
# Apply decay ranker to hybrid search
hybrid_results = milvus_client.hybrid_search(
    collection_name,
    [dense_request, sparse_request],
    #  highlight-next-line
    ranker=decay_ranker,                      # Same decay ranker works with hybrid search
    limit=10,
    output_fields=["document", "timestamp"]
)
// java
// nodejs
// go
# restful
在混合搜索中,Zilliz Cloud 首先从所有向量字段中找到最大相似度得分,然后对该得分应用衰减因子。