Select your Platform:
backend SDKs
client SDKs
Custom Ranking
Confused about "Custom Ranking"?
Let us know how we can improve our documentation:
Stream allows you to configure your own ranking method. You can add multiple ranking methods to a given feed group.
An example ranking config is shown below:
1
2
3
4
5
6
{
"score": "decay_linear(time) * popularity ^ 0.5",
"defaults": {
"popularity": 1
}
}
Available Functions
Copied!Confused about "Available Functions"?
Let us know how we can improve our documentation:
name | description |
---|---|
Basic Arithmetic | The following are supported: + - * / ( ) ^ |
ln(x) | Log Function natural base |
log(x) | Log Function base 10 |
sin(x) | Trigonometric sine function |
cos(x) | Trigonometric cosine function |
tan(x) | Trigonometric tangent 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 |
decay_exp(t) | Exponential Decay |
decay_gauss(t) | Gauss Decay |
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) |
rand(a,b) | Returns a random number in the range [a, b) |
to_unix_timestamp(t) | Converts a time value to a unix timestamp |
Adding Activities
Copied!Confused about "Adding Activities"?
Let us know how we can improve our documentation:
Below is an example of how to add activities with custom ranking:
1
2
3
4
5
6
7
8
9
10
11
// Server-Side: Instantiate a feed using feed class 'user' and user id '1'
const user1 = client.feed('user', '1');
// Client-Side: Instantiate a feed for feed group 'user', user id '1' and a security token generated server side
const user1 = client.feed('user', '1', token);
// Add an activity to the feed - adding your ranking method as a parameter (in this case, "popularity"):
const activity = { "actor": "User:2", "verb": "pin", "object": "Place:42", "target": "Board:1", "popularity": 5 };
// Add Activity
await user1.addActivity(activity);
1
2
3
4
5
6
7
8
# Instantiate a feed object
user_feed_1 = client.feed('user', '1')
# Add an activity to the feed, where actor, object and target are references to objects - adding your ranking method as a parameter (in this case, "popularity"):
activity_data = { "actor": "User:2", "verb": "pin", "object": "Place:42", "target": "Board:1", "popularity": 5 }
activity_response = user_feed_1.add_activity(activity_data)
1
2
3
4
5
6
7
# Instantiate a feed object
user_feed_1 = client.feed('user', '1')
# Add an activity to the feed - where actor, object, and target are references to objects - adding your ranking method as a parameter (in this case, "popularity"):
activity_data = { :actor => "User:2", :verb => "pin", :object => "Place:42", :target => "Board:1", :popularity => 5 }
activity_response = user_feed_1.add_activity(activity_data)
1
2
3
4
5
6
7
8
9
10
11
12
13
// Instantiate a feed object
$userFeed1 = $client->feed('user', '1');
// Add an activity to the feed, where actor, object and target are references to objects - and adding your ranking method as a parameter (in this case, "popularity"):
$data = [
"actor" =>"User:2",
"verb" =>"pin",
"object" =>"Place:42",
"target" =>"Board:1",
"popularity" => 5,
];
$userFeed1->addActivity($data);
1
2
3
4
5
6
7
8
9
// Add an activity to the feed, where actor, object and target are references to objects - adding your ranking method as a parameter (in this case, "popularity"):
Activity activity = Activity.builder()
.actor("User:1")
.verb("pin")
.object("place:42")
.target("board:1")
.extraField("popularity", 5)
.build();
userFeed.addActivity(activity).join();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// Instantiate a feed object
userFeed, _ := client.FlatFeed("user", "1")
// Add an activity to the feed, where actor, object and target are references to objects - adding your ranking method as a parameter (in this case, "popularity"):
activity := stream.Activity{
Actor: "User:1",
Verb: "pin",
Object: "Place:42",
Target: "Board:1",
Extra: map[string]interface{}{
"popularity": 5,
},
}
_, err := userFeed.AddActivity(activity)
if err != nil {
panic(err)
}
1
2
3
4
5
6
7
8
9
let user1 = client.flatFeed(feedSlug: "user", userId: "1")
let activity = Activity(actor: "User:1", verb: "pin", object: "Place:42")
user1.add(activity) { result in
if case .success(let activity) = result {
// Added activity
print(activity.id)
}
}
1
2
3
4
5
6
7
8
9
10
11
// Instantiate a feed object
var userFeed1 = client.Feed("user", "1");
// Add an activity to the feed, where actor, object and target are references to objects - adding your ranking method as a parameter (in this case, "popularity"):
var activity = new Activity("User:2", "pin", "Place:42")
{
Target = "Board:1"
};
activity.SetData("popularity", 5);
var activityResponse = await userFeed1.AddActivity(activity)
Retrieving Activities
Copied!Confused about "Retrieving Activities"?
Let us know how we can improve our documentation:
Below is an example of how to retrieve activities sorted by custom ranking:
1
2
// Get activities sorted by the ranking method labelled 'activity_popularity' (Ranked Feeds Enabled)
const response = await user1.get({ limit:20, ranking:'activity_popularity'});
1
2
# Get activities sorted by the ranking method labelled 'activity_popularity' (Ranked Feeds Enabled)
result = user_feed_1.get(limit=5, ranking="activity_popularity")
1
2
# Get activities sorted by the ranking method labelled 'activity_popularity' (Ranked Feeds Enabled)
result = user_feed_1.get(:limit=>5, :ranking=>'activity_popularity')
1
2
3
4
// Get 5 activities - using limit, offset - and sorted by the ranking method labelled 'activity_popularity' (Ranked Feeds Enabled):
$options = ['ranking' => 'activity_popularity'];
$results = $userFeed1->getActivities(0, 5, $options);
1
2
// Get activities sorted by the ranking method labelled 'activity_popularity' (Ranked Feeds Enabled)
response = userFeed.getActivities(new Pagination().limit(5), "activity_popularity").join();
1
2
3
4
5
6
7
8
// Get activities sorted by the ranking method labelled 'activity_popularity' (Ranked Feeds Enabled)
resp, err := userFeed.GetActivitiesWithRanking("activity_popularity", stream.WithActivitiesLimit(5))
if err != nil {
panic(err)
}
for _, activity := range resp.Results {
// ...
}
1
2
// Get activities sorted by the ranking method labelled 'activity_popularity' (Ranked Feeds Enabled):
user1.get(ranking: "activity_popularity")
1
2
// Get activities sorted by the ranking method labelled 'activity_popularity' (Ranked Feeds Enabled)
var result = await userFeed1.GetFlatActivities(GetOptions.Default.WithLimit(5).WithRanking("activity_popularity"));
Configuring ranking can be complex. Feel free to reach out to support if you have questions.
Decay & Ranking
Copied!Confused about "Decay & Ranking"?
Let us know how we can improve our documentation:
Stream supports a Linear, Exponential, and Gauss decay. For each decay function, we support 4 arguments: Origin, Scale, Offset, and Decay. You can pass either a timedelta string (such as 3d, 4w), or a numeric value.

Parameters
Copied!Confused about "Parameters"?
Let us know how we can improve our documentation:
name | description | default |
---|---|---|
origin | The best possible value. 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 will be equal to the decay value after 3 days. | 5d |
offset | Values below the offset will start to receive a lower score. | 0 |
decay | The score that a value at scale distance from the origin should receive. | 0.5 |
direction | left, right or both. If right is specified only apply the decay for the right part of the graph. | both |
The example below defines a simple_gauss with the following params:
scale: 5 days
offset: 1 day
decay: 0.3 day
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 full JSON config is shown below:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
{
"functions": {
"simple_gauss": {
"base":"decay_gauss",
"scale":"5d",
"offset":"1d",
"decay":"0.3"
},
"popularity_gauss": {
"base":"decay_gauss",
"scale":"100",
"offset":"5",
"decay":"0.5"
}
},
"defaults": {
"popularity": 1
},
"score":"simple_gauss(time)*popularity"
}
You can specify defaults for the variables you use. The example above sets popularity to 1 if it's missing from the activity. We highly recommend setting up defaults to prevent errors when retrieving activities without these variables.
Configuring ranking can be complex. Feel free to reach out to support if you have questions!