🚀 Try Zilliz Cloud, the fully managed Milvus, for free—experience 10x faster performance! Try Now>>

Milvus
Zilliz
Home
  • User Guide
  • Home
  • Docs
  • User Guide

  • Embeddings & Reranking

  • Reranking Function

  • Decay Ranker

  • Decay Ranker Overview

Decay Ranker OverviewCompatible with Milvus 2.6.x

In traditional vector search, results are ranked purely by vector similarity—how closely vectors match in mathematical space. But in real-world applications, what makes content truly relevant often depends on more than just semantic similarity.

Consider these everyday scenarios:

  • A news search where yesterday’s article should rank higher than a similar article from three years ago

  • A restaurant finder that prioritizes venues 5 minutes away over those requiring a 30-minute drive

  • An e-commerce platform that boosts trending products even when they’re slightly less similar to the search query

These scenarios all share a common need: balancing vector similarity with other numeric factors like time, distance, or popularity.

Decay rankers in Milvus address this need by adjusting search rankings based on numeric field values. They allow you to balance vector similarity with “freshness,” “nearness,” or other numeric properties of your data, creating more intuitive and contextually relevant search experiences.

Limits

  • Decay ranking cannot be used with grouping searches.

  • The field used for decay ranking must be numeric (INT8, INT16, INT32, INT64, FLOAT, or DOUBLE).

  • Each decay ranker can only use one numeric field.

How it works

Decay ranking enhances traditional vector search by incorporating numeric factors like time or geo distance into the ranking process. The entire process follows these stages:

Stage 1: Calculate normalized similarity scores

First, Milvus calculates and normalizes vector similarity scores to ensure consistent comparison:

  • For L2 and JACCARD distance metrics (where lower values indicate higher similarity):

    normalized_score = 1.0 - (2 × arctan(score))/π
    

    This transforms distances into similarity scores between 0-1, where higher is better.

  • For IP, COSINE, and BM25 metrics (where higher scores already indicate better matches): Scores are used directly without normalization.

Stage 2: Calculate decay scores

Next, Milvus calculates a decay score based on the numeric field value (like timestamp or distance) using your selected decay ranker:

  • Each decay ranker transforms raw numeric values into normalized relevance scores between 0-1

  • The decay score represents how relevant an item is based on its “distance” from the ideal point

The specific calculation formula varies depending on the decay ranker type. For details on how to calculate a decay score, refer to the dedicated pages for Gaussian Decay, Exponential Decay, Linear Decay.

Stage 3: Compute final scores

Finally, Milvus combines the normalized similarity score and decay score to produce the final ranking score:

final_score = normalized_similarity_score × decay_score

In cases of hybrid search (combining multiple vector fields), Milvus takes the maximum normalized similarity score among search requests:

final_score = max([normalized_score₁, normalized_score₂, ..., normalized_scoreₙ]) × decay_score

For example, if a research paper scores 0.82 from vector similarity and 0.91 from BM25-based text retrieval in a hybrid search, Milvus uses 0.91 as the base similarity score before applying the decay factor.

Decay ranking in action

Let’s see decay ranking in a practical scenario—searching for “AI research papers” with time-based decay:

In this example, decay scores reflect how relevance diminishes with time—newer papers receive scores closer to 1.0, older papers receive lower scores. These values are calculated using a specific decay ranker. For details, refer to Choose the right decay ranker.

Paper

Vector Similarity

Normalized Similarity Score

Publication Date

Decay Score

Final Score

Final Rank

Paper A

High

0.85 (COSINE)

2 weeks ago

0.80

0.68

2

Paper B

Very High

0.92 (COSINE)

6 months ago

0.45

0.41

3

Paper C

Medium

0.75 (COSINE)

1 day ago

0.98

0.74

1

Paper D

Medium-High

0.76 (COSINE)

3 weeks ago

0.70

0.53

4

Without decay reranking, Paper B would rank highest based on pure vector similarity (0.92). However, with decay reranking applied:

  • Paper C jumps to position #1 despite medium similarity because it’s very recent (published yesterday)

  • Paper B drops to position #3 despite excellent similarity because it’s relatively old

  • Paper D uses L2 distance (where lower is better), so its score is normalized from 1.2 to 0.76 before applying decay

Choose the right decay ranker

Milvus offers distinct decay rankers - gauss, exp, linear, each designed for specific use cases:

Decay Ranker

Characteristics

Ideal Use Cases

Example Scenario

Gaussian (gauss)

Natural-feeling gradual decline that extends moderately

  • General searches requiring balanced results

  • Applications where users have an intuitive sense of distance

  • When moderate distance shouldn't severely penalize results

In a restaurant search, quality venues 3 km away remain discoverable, though ranked lower than nearby options

Exponential (exp)

Rapidly decreases at first but maintains a long tail

  • News feeds where recency is critical

  • Social media where fresh content should dominate

  • When proximity is strongly preferred but exceptional distant items should remain visible

In a news app, yesterday's stories rank much higher than week-old content, but highly relevant older articles can still appear

Linear (linear)

Consistent, predictable decline with a clear cutoff

  • Applications with natural boundaries

  • Services with distance limits

  • Content with expiration dates or clear thresholds

In an event finder, events beyond a two-week future window simply don't appear at all

For detailed information about how each decay ranker calculates scores and specific decline patterns, refer to the dedicated documentation:

Implementation example

Decay rankers can be applied to both standard vector search and hybrid search operations in Milvus. Below are the key code snippets for implementing this feature.

Before using decay functions, you must first create a collection with appropriate numeric fields (like timestamps, distances, etc.) that will be used for decay calculations. For complete working examples including collection setup, schema definition, and data insertion, refer to Tutorial: Implement Time-based Ranking in Milvus.

Create a decay ranker

To implement decay ranking, first define a Function object with the appropriate configuration:

from pymilvus import Function, FunctionType

# Create a decay function for timestamp-based decay
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
        "scale": 7 * 24 * 60 * 60,      # 7 days in seconds
        "offset": 24 * 60 * 60,         # 1 day no-decay zone
        "decay": 0.5                    # Half score at scale distance
    }
)

Parameter

Required?

Description

Value/Example

name

Yes

Identifier for your function used when executing searches. Choose a descriptive name relevant to your use case.

"time_decay"

input_field_names

Yes

Numeric field for decay score calculation. Determines which data attribute will be used for calculating decay (e.g., timestamps for time-based decay, coordinates for location-based decay). Must be a field in your collection that contains relevant numeric values. Supports INT8/16/32/64, FLOAT, DOUBLE.

["timestamp"]

function_type

Yes

Specifies the type of function being created. Must be set to RERANK for all decay rankers.

FunctionType.RERANK

params.reranker

Yes

Specifies the reranking method to use. Must be set to "decay" to enable decay ranking functionality.

"decay"

params.function

Yes

Specifies which mathematical decay ranker to apply. Determines the curve shape of relevance decline. See Choose the right decay ranker section for guidance on selecting the appropriate function.

"gauss", "exp", or "linear"

params.origin

Yes

Reference point from which decay score is calculated. Items at this value receive maximum relevance scores.

  • For timestamps: current time (e.g., int(time.time()))
  • For geolocation: user's current coordinates

params.scale

Yes

Distance or time at which relevance drops to the decay value. Controls how quickly relevance declines. Larger values create a more gradual decline in relevance; smaller values create a steeper decline.

  • For time: period in seconds (e.g., 7 * 24 * 60 * 60 for 7 days)
  • For distance: meters (e.g., 5000 for 5km)

params.offset

No

Creates a "no-decay zone" around the origin where items maintain full scores (decay score = 1.0). Items within this range of the origin maintain maximum relevance.

  • For time: period in seconds (e.g., 24 * 60 * 60 for 1 day)
  • For distance: meters (e.g., 500 for 500m)

params.decay

No

Score value at the scale distance, controls curve steepness. Lower values create steeper decline curves; higher values create more gradual decline curves. Must be between 0 and 1.

0.5 (default)

After defining your decay ranker, you can apply it during search operations by passing it to the ranker parameter:

# 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
    ranker=decay_ranker,                      # Apply the decay ranker here
    consistency_level="Strong"
)

Decay rankers can also be applied to hybrid search operations that combine multiple vector fields:

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],
    ranker=decay_ranker,                      # Same decay ranker works with hybrid search
    limit=10,
    output_fields=["document", "timestamp"]
)

In hybrid search, Milvus first finds the maximum similarity score from all vector fields, then applies the decay factor to that score.

Try Managed Milvus for Free

Zilliz Cloud is hassle-free, powered by Milvus and 10x faster.

Get Started
Feedback

Was this page helpful?