# Ranking expressions

A ranking expression computes a score for each activity, and the feed is ordered by that score, highest first. This page is the reference for what an `expression` or `interest` ranking can use: activity fields, data types, functions, operators, constants and decay functions. For how to configure ranking on a feed group or feed view, see [Ranking](https://getstream.io/activity-feeds/docs/dotnet-csharp/custom-ranking/).

## Activity data

It's not possible to access all fields of an `ActivityResponse` inside the ranking context. Below you'll find the list of supported fields:

| name               | description                                                                                                                                                                                                                                                                                                                                                          |
| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `type`             | The type of the activity (e.g. the content type string set when creating the activity)                                                                                                                                                                                                                                                                               |
| `time`             | UNIX timestamp of when the activity was created                                                                                                                                                                                                                                                                                                                      |
| `popularity`       | The popularity score of an activity (formula: `activity.popularity = reactions + comments * 2 + bookmarks * 3 + shares * 3`)                                                                                                                                                                                                                                         |
| `reaction_count`   | The sum of all reactions                                                                                                                                                                                                                                                                                                                                             |
| `reaction_counts`  | Reaction counts by type, you can access specific types with dot notation (for example, `reaction_counts.like`)                                                                                                                                                                                                                                                       |
| `comment_count`    | How many comments the activity has                                                                                                                                                                                                                                                                                                                                   |
| `bookmark_count`   | How many bookmarks the activity has                                                                                                                                                                                                                                                                                                                                  |
| `share_count`      | How many shares the activity has (Increased when an activity is set as the `parent_id` of another activity)                                                                                                                                                                                                                                                          |
| `custom`           | The `custom` field of the `activity`, nested fields can be accessed with `.` notation, for example: `custom.topic`                                                                                                                                                                                                                                                   |
| `selector_source`  | Which activity selector provided this activity (e.g., `"following"`, `"popular"`, `"interest"`). See [Ranking by Selector Source](#ranking-by-selector-source) for usage examples.                                                                                                                                                                                   |
| `interest_score`   | Only available when using `interest` type ranking. A number between -1 and 1 reflecting how much a given activity matches the user's interests. See [Interest weights](https://getstream.io/activity-feeds/docs/dotnet-csharp/interest-ranking/) to see how a user's interests are computed/configured.                                                                                     |
| `preference_score` | Available when using `expression` or `interest` type ranking. A number reflecting how much a given activity matches the user's preferences based on activity feedback (show more/less). Activities with `interest_tags` that have strong dislike are filtered out. See [Activity feedback](https://getstream.io/activity-feeds/docs/dotnet-csharp/activity-feedback/) for more information. |
| `is_read`          | Boolean. Available when `track_read` is enabled on a custom feed group or the built-in `notification` group (including flat). `true` if the activity (or its aggregated group) has been marked as read. Uses time-based invalidation. **Enterprise plan only.** See [Ranking by Read/Seen Status](https://getstream.io/activity-feeds/docs/dotnet-csharp/read-seen-ranking/).               |
| `is_seen`          | Boolean. Available when `track_seen` is enabled on a custom feed group or the built-in `notification` group (including flat). Same time-based invalidation as `is_read`. **Enterprise plan only.** See [Ranking by Read/Seen Status](https://getstream.io/activity-feeds/docs/dotnet-csharp/read-seen-ranking/).                                                                            |

Every field the expression references that isn't a built-in field, such as `custom.*`, `external.*`, `metrics.*` and `selector_source`, needs a default value in `defaults`. The default is used for activities that don't have the field, and creating or updating a feed group or feed view without it fails with `expression references fields without defaults: <field>`. Write defaults as nested objects (`{ "custom": { "foo": 0 } }`), not dotted keys (`"custom.foo"`). Built-in fields such as `popularity` or `share_count` can't have defaults.

```csharp label="C#"
await _feedsV3Client.CreateFeedGroupAsync(new CreateFeedGroupRequest
{
    ID = "myid",
    ActivitySelectors = new List<ActivitySelectorConfig>
    {
        new() { Type = "following" }
    },
    Ranking = new RankingConfig
    {
        Type = "expression",
        Score = "popularity * (custom.isBoosted ? 1.5 : 1)",
        Defaults = new Dictionary<string, object>
        {
            ["custom"] = new Dictionary<string, object> { ["isBoosted"] = false }
        }
    }
});
```

## Data types

The following data types are supported in the ranking expression context:

| name    | example           |
| ------- | ----------------- |
| Boolean | `true`, `false`   |
| Integer | `36`, `0b101010`  |
| Float   | `0.2`             |
| String  | `"foo"`           |
| Array   | `["a", "b", "c"]` |
| Map     | `{foo: "bar"}`    |
| Nil     | `nil`             |

## Functions

The following functions can be used in ranking expressions:

| name                           | description                                                                                                                                                                                                                                                                                                                                                                                        |
| ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ln(x)                          | Natural logarithm function                                                                                                                                                                                                                                                                                                                                                                         |
| log10(x)                       | Logarithm function base 10                                                                                                                                                                                                                                                                                                                                                                         |
| sin(x)                         | Trigonometric sine function                                                                                                                                                                                                                                                                                                                                                                        |
| cos(x)                         | Trigonometric cosine function                                                                                                                                                                                                                                                                                                                                                                      |
| tan(x)                         | Trigonometric tangent function                                                                                                                                                                                                                                                                                                                                                                     |
| asin(x)                        | Arcsine function                                                                                                                                                                                                                                                                                                                                                                                   |
| acos(x)                        | Arccosine function                                                                                                                                                                                                                                                                                                                                                                                 |
| atan(x)                        | Arctangent function                                                                                                                                                                                                                                                                                                                                                                                |
| abs(x)                         | Absolute value                                                                                                                                                                                                                                                                                                                                                                                     |
| min(a,b)                       | Minimum value                                                                                                                                                                                                                                                                                                                                                                                      |
| max(a,b)                       | Maximum value                                                                                                                                                                                                                                                                                                                                                                                      |
| trunc(x)                       | Truncates to the nearest integer value                                                                                                                                                                                                                                                                                                                                                             |
| round(x)                       | Rounds to the nearest integer value                                                                                                                                                                                                                                                                                                                                                                |
| decay_linear(t)                | Linear decay, see [Decay & Ranking](#decay--ranking) for more information                                                                                                                                                                                                                                                                                                                          |
| decay_exp(t)                   | Exponential decay, see [Decay & Ranking](#decay--ranking) for more information                                                                                                                                                                                                                                                                                                                     |
| decay_gauss(t)                 | Gaussian decay, see [Decay & Ranking](#decay--ranking) for more information                                                                                                                                                                                                                                                                                                                        |
| rand_normal()                  | Returns a normally distributed number in the range [-inf, +inf] with standard normal distribution (stddev = 1, mean = 0)                                                                                                                                                                                                                                                                           |
| rand_normal(a,b,σ,µ)           | Returns a normally distributed number in the range [a, b] with specific normal distribution (stddev = σ, mean = µ)                                                                                                                                                                                                                                                                                 |
| rand()                         | Returns a random number in the range [0, 1.0)                                                                                                                                                                                                                                                                                                                                                      |
| to_unix_timestamp(t)           | Converts a time value to a UNIX timestamp                                                                                                                                                                                                                                                                                                                                                          |
| dist(lat1,lng1,lat2,lng2,unit) | Returns the distance between the two points given by (lat1,lng1) and (lat2,lng2). By default the unit is in kilometers, but the unit can also be `"M"` for miles or `"N"` for nautical miles. Coordinates written in the expression must be decimals (`51.0`, not `51`). This function can be combined with the external ranking parameters to rank activities based on a user's distance to them. |
| map_lookup(key, map)           | Look up value from a map by key (`0.0` if the key is missing), see [Arrays and Maps](https://getstream.io/activity-feeds/docs/dotnet-csharp/external-ranking-data/#arrays-and-maps) for more information                                                                                                                                                                                                                  |
| sum_map_lookup(keys, map)      | Sum values from a map for multiple keys, see [Arrays and Maps](https://getstream.io/activity-feeds/docs/dotnet-csharp/external-ranking-data/#arrays-and-maps) for more information                                                                                                                                                                                                                                        |
| in_array(needle, haystack)     | Returns `1.0` if a value exists in an array and `0.0` otherwise, see [Arrays and Maps](https://getstream.io/activity-feeds/docs/dotnet-csharp/external-ranking-data/#arrays-and-maps) for more information                                                                                                                                                                                                                |

## Operators

The following operators can be used in ranking expressions:

- Arithmetic operators: `+`, `-`, `*`, `/`, `%` (modulus), `^`, `**` (exponent)

- Logical operators: `not`/`!`, `&&`/ `and`, `||`/`or`

- Conditional: `x ? y : z`, `??`, `if`/`else`

- Comparison: `==`, `!=`, `<`, `>`, `<=`, `>=`

- Control order of evaluation with parentheses `()`

- Array/map operators: `[]` (index), `.`, `?.`, `in` (checks if an array/map has an item/key)

- String operators: `+` (concatenation), `contains`, `startsWith`, `endsWith`

This lets you construct a scoring algorithm like this:

```text
"score":"(a > 2 || (b > 4 && c > 3)) ? 1 : -1"
```

## Constants

The following constants and helpers are also available to use in ranking expressions:

| name           | description                        |
| -------------- | ---------------------------------- |
| `e` / `E`      | Euler's number                     |
| `pi` / `PI`    | π                                  |
| `current_time` | UNIX timestamp of the current time |

## Decay & Ranking

Stream supports linear, exponential, and Gaussian decay. The built-in `decay_linear(t)`, `decay_exp(t)` and `decay_gauss(t)` take one argument and always use the default parameters below (origin now, scale 5 days, no offset, decay 0.5); extra arguments are ignored. To change the parameters, define your own function under `functions` with a `base` of `decay_linear`, `decay_exp` or `decay_gauss`, and call it by name in `score`. All parameter values are strings.

![](https://getstream.imgix.net/images/docs/decay_explainer.png?auto=compress&fit=clip&w=800&h=600)

### Parameters

| name      | description                                                                                                                                                                                  | default |
| --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
| base      | Required. The decay function to use: `decay_linear`, `decay_exp` or `decay_gauss`.                                                                                                           |         |
| origin    | The best possible value, as a number (for example a UNIX timestamp, or a popularity). If the value is equal to the origin, the decay function will return 1.                                 | now     |
| scale     | Determines how quickly the score drops from 1.0 to the decay value. If the scale is set to "3d", the score is equal to the decay value 3 days beyond the offset.                             | 5d      |
| offset    | Values within the offset of the origin score 1. The decay starts beyond the offset.                                                                                                          | 0       |
| decay     | The score that a value at scale distance from the origin should receive.                                                                                                                     | 0.5     |
| direction | `both`, `right` or `left`. With `right`, only values below the origin decay (for timestamps, older activities) and values above it score 1. With `left`, only values above the origin decay. | both    |

>
> **Info:** For `scale` and `offset` you can use s, m, h, d, w and y to specify seconds, minutes, hours, days, weeks and years, with a whole number (for example `36h`, not `1.5d`). A plain number is used as is.
>

The example below defines a simple_gauss with the following parameters:

- **scale**: 5 days

- **offset**: 1 day

- **decay**: 0.3

This means that an activity younger than 1 day (the offset) will return a score of 1. An activity that is exactly 6 days old (offset + scale) will get a score of 0.3 (the decay factor).

The example also defines a `popularity_gauss` that scores activities with a popularity of 100 or more as 1 (`origin: "100"` with `direction: "right"`), and lowers the score of less popular activities. A function applied to something other than time needs an `origin`, because the default origin is the current time. The full example:

```csharp label="C#"
await _feedsV3Client.CreateFeedGroupAsync(new CreateFeedGroupRequest
{
    ID = "myid",
    ActivitySelectors = new List<ActivitySelectorConfig>
    {
        new() { Type = "following" }
    },
    Ranking = new RankingConfig
    {
        Type = "expression",
        Score = "simple_gauss(time)*popularity_gauss(popularity)",
        Functions = new Dictionary<string, DecayFunctionConfig>
        {
            ["simple_gauss"] = new()
            {
                Base = "decay_gauss",
                Scale = "5d",
                Offset = "1d",
                Decay = "0.3"
            },
            ["popularity_gauss"] = new()
            {
                Base = "decay_gauss",
                Origin = "100",
                Direction = "right",
                Scale = "100",
                Offset = "5",
                Decay = "0.5"
            }
        }
    }
});
```

## Ranking by Selector Source

When using multiple [activity selectors](https://getstream.io/activity-feeds/docs/dotnet-csharp/activity-selectors/), each activity is tagged with a `selector_source` field indicating which selector provided it. This enables you to prioritize activities from specific sources in your ranking expressions.

```csharp label="C#"
// Example 1: Simple boost - following activities get 2x multiplier
await _feedsV3Client.CreateFeedGroupAsync(new CreateFeedGroupRequest
{
    ID = "selector_timeline",
    ActivitySelectors = new List<ActivitySelectorConfig>
    {
        new() { Type = "following" },
        new() { Type = "popular", MinPopularity = 1 }
    },
    Ranking = new RankingConfig
    {
        Type = "expression",
        Score = "selector_source == \"following\" ? popularity * 2 : popularity",
        // Required when using selector_source in expressions
        Defaults = new Dictionary<string, object> { ["selector_source"] = "" }
    }
});

// Example 2: Multiple selectors with different bonuses
await _feedsV3Client.CreateFeedGroupAsync(new CreateFeedGroupRequest
{
    ID = "multi_selector_timeline",
    ActivitySelectors = new List<ActivitySelectorConfig>
    {
        new() { Type = "following" },
        new() { Type = "interest" },
        new() { Type = "popular", MinPopularity = 1 }
    },
    Ranking = new RankingConfig
    {
        Type = "expression",
        Score = "(selector_source == \"following\" ? 10 : 0) + " +
            "(selector_source == \"interest\" ? 5 : 0) + " +
            "popularity",
        Defaults = new Dictionary<string, object> { ["selector_source"] = "" }
    }
});
```

**Important notes:**

- **Defaults required:** You must provide `selector_source` in the `defaults` map (typically as an empty string `""`)
- **Duplicate activities:** If an activity matches multiple selectors, it keeps a single `selector_source`. `following` takes precedence over the other selectors
- **Valid sources:** `following`, `popular`, `interest`, `query`, `proximity`, `current_feed`, `follow_suggestion`

---

For the most recent version of this documentation, visit [https://getstream.io/activity-feeds/docs/dotnet-csharp/ranking-expressions/](https://getstream.io/activity-feeds/docs/dotnet-csharp/ranking-expressions/).