Search needs to be flexible.
Depending on the user’s context, results can vary.
For example, because some products are more likely to be bought or viewed from phones than desktops, you may want to promote items based on the user’s device.
To do this:
- Identify your user’s device.
- Assign a
mobile
context when users search from mobile devices. A context is a string passed as a search parameter to InstantSearch or an Algolia API client.
- Create a contextual rule that acts on the
mobile
context.
To help understand user behavior across devices, pair your device-specific experience with analytics. You can even use the same context string to tag search queries for analytics. These analyticsTags
help you group search analytics into different segments.
Example scenario
Suppose you work for a movie database company.
Research shows that mobile users, unlike desktop users, tend to see a film in theaters after it has appeared in their search results.
To capitalize on this, you partner with a movie theater chain and decide to promote newly released movies to your mobile users.
The records in your Algolia index include a release_date
attribute, in Unix timestamp format, this is useful for identifying newly released movies.
1
2
3
4
5
6
7
| {
"title": "Fargo",
"year": 1996,
"director": "Joel Coen",
"release_date": 841795200,
"rating": 93
}
|
By creating a mobile context and contextual rules, you can promote recent movies to mobile users.
Identify your user’s device
Before assigning a mobile context to searches, write a function that detects what device the app is running on, and return “desktop” or “mobile” depending on what it finds:
1
2
3
4
5
| const getPlatform = () => {
// const isMobile = ...
// Your logic to determine whether a user is on a mobile or desktop device
return isMobile ? 'mobile' : 'desktop';
};
|
Assign context
You can assign context with InstantSearch or an Algolia API client.
Assign context with InstantSearch
Set the user’s device context at the beginning of their search session by adding it to the searchParameters
setting of your InstantSearch instance during initialization.
1
2
3
4
5
| const platformTag = getPlatform();
instantsearch.widgets.configure({
ruleContexts: [platformTag],
});
|
1
2
3
4
5
| let platform = getPlatform()
let searcher = HitsSearcher(appId: "YourAppId", apiKey: "YourAPIKey", indexName: "YourIndexName")
searcher.request.query.ruleContexts = [platform]
|
1
2
3
4
5
6
7
| import { Configure } from 'react-instantsearch';
const platformTag = getPlatform()
<Configure
ruleContexts=[platformTag]
/>
|
1
2
3
4
5
6
7
8
9
| <script>
export default {
data() {
return {
ruleContexts: getPlatform(),
};
},
};
</script>
|
1
2
3
| <ais-configure>
[searchParameters]="{ ruleContexts: [getPlatform()]}"
</ais-configure>
|
1
2
3
4
5
6
7
8
| val platform: String = getPlatform()
val query = query {
ruleContexts {
+platform
}
}
val searcher = HitsSearcher(movies, query)
|
Assign context with an API client
Pass the user’s device context as a search parameter whenever you search
your index.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
| namespace Algolia;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
using Algolia.Search.Clients;
using Algolia.Search.Http;
using Algolia.Search.Models.Search;
class SearchWithRuleContexts
{
private static string GetPlatformTag()
{
return ""; // Implement your logic here
}
async Task Main(string[] args)
{
var client = new SearchClient(new SearchConfig("ALGOLIA_APPLICATION_ID", "ALGOLIA_API_KEY"));
var platformTag = GetPlatformTag();
var searchParams = new SearchParams(
new SearchParamsObject { Query = "<YOUR_SEARCH_QUERY>", RuleContexts = [platformTag] }
);
await client.SearchSingleIndexAsync<Hit>("<YOUR_INDEX_NAME>", searchParams);
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| import 'package:algolia_client_search/algolia_client_search.dart';
String getPlatformTag() {
return ""; // Implement your logic here
}
void searchWithRuleContexts() async {
final client =
SearchClient(appId: 'ALGOLIA_APPLICATION_ID', apiKey: 'ALGOLIA_API_KEY');
final platformTag = getPlatformTag();
final searchParams = SearchParamsObject(
query: "<YOUR_SEARCH_QUERY>", ruleContexts: [platformTag]);
await client.searchSingleIndex(
indexName: "<YOUR_INDEX_NAME>",
searchParams: searchParams,
);
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
| package main
import "github.com/algolia/algoliasearch-client-go/v4/algolia/search"
func getPlatformTag() (string, error) {
return "", nil // Implement your logic here
}
func searchWithRuleContexts() {
client, err := search.NewClient("ALGOLIA_APPLICATION_ID", "ALGOLIA_API_KEY")
if err != nil {
// The client can fail to initialize if you pass an invalid parameter.
panic(err)
}
platformTag, err := getPlatformTag()
if err != nil {
panic(err)
}
searchParams := search.SearchParamsObjectAsSearchParams(
search.NewSearchParamsObject().
SetQuery("<YOUR_SEARCH_QUERY>").
SetRuleContexts([]string{platformTag}),
)
_, err = client.SearchSingleIndex(client.NewApiSearchSingleIndexRequest(
"<YOUR_INDEX_NAME>").WithSearchParams(searchParams))
if err != nil {
panic(err)
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| package com.algolia;
import com.algolia.api.SearchClient;
import com.algolia.config.*;
import com.algolia.model.search.*;
import java.util.List;
public class searchWithRuleContexts {
private static String getPlatformTag() {
return ""; // Implement your logic here
}
public static void main(String[] args) throws Exception {
try (SearchClient client = new SearchClient("ALGOLIA_APPLICATION_ID", "ALGOLIA_API_KEY");) {
String platformTag = getPlatformTag();
SearchParams searchParams = new SearchParamsObject().setQuery("<YOUR_SEARCH_QUERY>").setRuleContexts(List.of(platformTag));
client.searchSingleIndex("<YOUR_INDEX_NAME>", searchParams, Hit.class);
} catch (Exception e) {
System.out.println("An error occurred: " + e.getMessage());
}
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| import type { SearchParams } from 'algoliasearch';
import { algoliasearch } from 'algoliasearch';
const getPlatformTag = () => {
return ''; // Implement your logic here
};
const client = algoliasearch('ALGOLIA_APPLICATION_ID', 'ALGOLIA_API_KEY');
const platformTag = getPlatformTag();
const searchParams: SearchParams = {
query: '<YOUR_SEARCH_QUERY>',
ruleContexts: [platformTag],
};
await client.searchSingleIndex({ indexName: 'indexName', searchParams: searchParams });
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
| import com.algolia.client.api.SearchClient
import com.algolia.client.configuration.*
import com.algolia.client.transport.*
import com.algolia.client.extensions.*
import com.algolia.client.model.search.*
val getPlatformTag: () -> String = {
"" // Implement your logic here
}
suspend fun searchWithRuleContexts() {
val client = SearchClient(appId = "ALGOLIA_APPLICATION_ID", apiKey = "ALGOLIA_API_KEY")
val platformTag = getPlatformTag()
val searchParams = SearchParamsObject(
query = "<YOUR_SEARCH_QUERY>",
ruleContexts = listOf(platformTag),
)
client.searchSingleIndex(
indexName = "<YOUR_INDEX_NAME>",
searchParams = searchParams,
)
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| <?php
require __DIR__.'/../vendor/autoload.php';
use Algolia\AlgoliaSearch\Api\SearchClient;
use Algolia\AlgoliaSearch\Model\Search\SearchParamsObject;
$getPlatformTag = function (): string {
// Implement your logic here
return '';
};
$client = SearchClient::create('ALGOLIA_APPLICATION_ID', 'ALGOLIA_API_KEY');
// get the buyer account information
$platformTag = $getPlatformTag();
$searchParams = (new SearchParamsObject())
->setQuery('<YOUR_SEARCH_QUERY>')
->setRuleContexts([$platformTag])
;
$client->searchSingleIndex(
'<YOUR_INDEX_NAME>',
$searchParams,
);
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| from algoliasearch.search.client import SearchClientSync
from algoliasearch.search.models.search_params import SearchParams
def _get_platform_tag() -> str:
# Implement your logic here
return ""
_client = SearchClientSync("ALGOLIA_APPLICATION_ID", "ALGOLIA_API_KEY")
# get the buyer account information
platform_tag = _get_platform_tag()
search_params = SearchParams(
query="<YOUR_SEARCH_QUERY>",
rule_contexts=[platform_tag],
)
_client.search_single_index(
index_name="<YOUR_INDEX_NAME>",
search_params=search_params,
)
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| require "algolia"
def get_platform_tag
# Implement your logic here
""
end
client = Algolia::SearchClient.create("ALGOLIA_APPLICATION_ID", "ALGOLIA_API_KEY")
# get the buyer account information
platform_tag = get_platform_tag
search_params = Algolia::Search::SearchParamsObject.new(
query: "<YOUR_SEARCH_QUERY>",
rule_contexts: [platform_tag]
)
client.search_single_index("<YOUR_INDEX_NAME>", search_params)
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
| import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
import algoliasearch.api.SearchClient
import algoliasearch.config.*
import algoliasearch.extension.SearchClientExtensions
import algoliasearch.search.SearchParamsObject
val getPlatformTag: String = {
"" // Implement your logic here
}
def searchWithRuleContexts(): Future[Unit] = {
val client = SearchClient(appId = "ALGOLIA_APPLICATION_ID", apiKey = "ALGOLIA_API_KEY")
val platformTag = getPlatformTag
val searchParams = SearchParamsObject(
query = Some("<YOUR_SEARCH_QUERY>"),
ruleContexts = Some(Seq(platformTag))
)
client
.searchSingleIndex(
indexName = "<YOUR_INDEX_NAME>",
searchParams = Some(searchParams)
)
.map { response =>
println(response)
}
.recover { case ex: Exception =>
println(s"An error occurred: ${ex.getMessage}")
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| import Foundation
#if os(Linux) // For linux interop
import FoundationNetworking
#endif
import Core
import Search
let getPlatformTag = { "" } // Implement your logic here
func searchWithRuleContexts() async throws {
let client = try SearchClient(appID: "ALGOLIA_APPLICATION_ID", apiKey: "ALGOLIA_API_KEY")
let platformTag = getPlatformTag()
let searchParams = SearchSearchParams.searchSearchParamsObject(
SearchSearchParamsObject(query: "<YOUR_SEARCH_QUERY>", ruleContexts: [platformTag])
)
let response: SearchResponse<Hit> = try await client.searchSingleIndex(
indexName: "<YOUR_INDEX_NAME>",
searchParams: searchParams
)
print(response)
}
|
Create a contextual rule
You can create a mobile contextual rule with an API client or from the Algolia dashboard.
Create a contextual rule with an API client
Use the save-rule
method to create a context-dependent rule.
For example, to promote movies released after January 1, 2020, for mobile users:
1
2
3
4
5
6
7
8
9
10
11
12
13
| var response = await client.SaveRuleAsync(
"ALGOLIA_INDEX_NAME",
"a-rule-id",
new Rule
{
ObjectID = "a-rule-id",
Conditions = new List<Condition> { new Condition { Context = "mobile" } },
Consequence = new Consequence
{
Params = new ConsequenceParams { Filters = "release_date >= 1577836800" },
},
}
);
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| final response = await client.saveRule(
indexName: "ALGOLIA_INDEX_NAME",
objectID: "a-rule-id",
rule: Rule(
objectID: "a-rule-id",
conditions: [
Condition(
context: "mobile",
),
],
consequence: Consequence(
params: ConsequenceParams(
filters: "release_date >= 1577836800",
),
),
),
);
|
1
2
3
4
5
6
7
8
9
10
| response, err := client.SaveRule(client.NewApiSaveRuleRequest(
"ALGOLIA_INDEX_NAME", "a-rule-id",
search.NewEmptyRule().SetObjectID("a-rule-id").SetConditions(
[]search.Condition{*search.NewEmptyCondition().SetContext("mobile")}).SetConsequence(
search.NewEmptyConsequence().SetParams(
search.NewEmptyConsequenceParams().SetFilters("release_date >= 1577836800")))))
if err != nil {
// handle the eventual error
panic(err)
}
|
1
2
3
4
5
6
7
8
| client.saveRule(
"ALGOLIA_INDEX_NAME",
"a-rule-id",
new Rule()
.setObjectID("a-rule-id")
.setConditions(Arrays.asList(new Condition().setContext("mobile")))
.setConsequence(new Consequence().setParams(new ConsequenceParams().setFilters("release_date >= 1577836800")))
);
|
1
2
3
4
5
6
7
8
9
| const response = await client.saveRule({
indexName: 'indexName',
objectID: 'a-rule-id',
rule: {
objectID: 'a-rule-id',
conditions: [{ context: 'mobile' }],
consequence: { params: { filters: 'release_date >= 1577836800' } },
},
});
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| var response = client.saveRule(
indexName = "ALGOLIA_INDEX_NAME",
objectID = "a-rule-id",
rule = Rule(
objectID = "a-rule-id",
conditions = listOf(
Condition(
context = "mobile",
),
),
consequence = Consequence(
params = ConsequenceParams(
filters = "release_date >= 1577836800",
),
),
),
)
|
1
2
3
4
5
6
7
8
9
10
11
12
13
| $response = $client->saveRule(
'ALGOLIA_INDEX_NAME',
'a-rule-id',
['objectID' => 'a-rule-id',
'conditions' => [
['context' => 'mobile',
],
],
'consequence' => ['params' => ['filters' => 'release_date >= 1577836800',
],
],
],
);
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| response = client.save_rule(
index_name="ALGOLIA_INDEX_NAME",
object_id="a-rule-id",
rule={
"objectID": "a-rule-id",
"conditions": [
{
"context": "mobile",
},
],
"consequence": {
"params": {
"filters": "release_date >= 1577836800",
},
},
},
)
|
1
2
3
4
5
6
7
8
9
10
11
| response = client.save_rule(
"ALGOLIA_INDEX_NAME",
"a-rule-id",
Algolia::Search::Rule.new(
algolia_object_id: "a-rule-id",
conditions: [Algolia::Search::Condition.new(context: "mobile")],
consequence: Algolia::Search::Consequence.new(
params: Algolia::Search::ConsequenceParams.new(filters: "release_date >= 1577836800")
)
)
)
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| val response = Await.result(
client.saveRule(
indexName = "ALGOLIA_INDEX_NAME",
objectID = "a-rule-id",
rule = Rule(
objectID = "a-rule-id",
conditions = Some(
Seq(
Condition(
context = Some("mobile")
)
)
),
consequence = Consequence(
params = Some(
ConsequenceParams(
filters = Some("release_date >= 1577836800")
)
)
)
)
),
Duration(100, "sec")
)
|
1
2
3
4
5
6
7
8
9
| let response = try await client.saveRule(
indexName: "ALGOLIA_INDEX_NAME",
objectID: "a-rule-id",
rule: Rule(
objectID: "a-rule-id",
conditions: [SearchCondition(context: "mobile")],
consequence: SearchConsequence(params: SearchConsequenceParams(filters: "release_date >= 1577836800"))
)
)
|
Create a contextual rule with the dashboard
- Select the Search product icon on your dashboard.
- Select the Rules section from the left sidebar menu in the Algolia dashboard.
- Under the heading Rules, select the index to which you’re adding a rule.
- Select Create your first rule or New rule. In the drop-down menu, click the Manual Editor option.
- In the Condition(s) section, toggle Context on and toggle Query off.
- Enter “mobile” in the context input field.
- In the Consequence(s) sections, click Add Consequence and select the Add Query Parameter consequence.
-
In the editor, add a filter for the release_date
attribute.
For example, to show all movies released since 2020 (1577836800
is the Unix timestamp for January 1, 2020),
enter: { "filters": "release_date >= 1577836800" }
- If you wish, you can add other consequences by clicking Add consequence. For example, there may be movies that you want to pin to a specific location or rank at the top,
- Save your changes.