You can send events one by one, as soon as they occur, or in batches. How to send events depends on your implementation. There are some situations where you can’t or don’t want to send events as soon as they occur. In that case, you can collect events and send them in batches. You may also want to send historical data as events, which you can do more efficiently in batches.
Collecting and batching events as they occur
You may want to collect events from your front end without immediately sending them to Algolia. One reason to do this is to avoid making too many HTTP requests. In that case, you can collect events during predefined time periods and send them in batches.
You can apply this strategy for both search-related events and events that occur outside of the search context. For example, you can send conversion events when a user directly lands on a product page and makes a purchase, or even when they buy an item in a brick-and-mortar store. Instead of sending conversion events as soon as these occur, you can collect them and send them at regular time intervals, like every hour or day.
Another reason you may want batch events is to run them through some sort of algorithm or filtering process before sending them.
Sending historical data
You may want to send historical data from Google Analytics or another provider that is useful for building your Personalization strategy. Sending events for this historical data makes it available for Personalization, even when you haven’t collected any events from your Algolia implementation yet. Instead of sending each event, one by one, it’s more efficient to send historical data in batches.
When sending historical data, it’s important to include a timestamp
of when the events occurred. To keep the effects of Personalization current, the engine doesn’t consider events that are older than 90 days.
Though the Personalization feature uses events that are up to 90 days old, the Insights API rejects events that occurred earlier than four days ago.
If you are using the API clients to send events, and you don’t include a timestamp
, the current time is used. Thus, it can be tempting to send all your historical data using the current time as the timestamp
. This isn’t a good idea because it creates a data “cliff”—once the data becomes 90 days old, the way Personalization works can radically change.
Search-related events must occur within one hour of their search. In other words, after a user searches, the analytics engine only counts events related to that search if they have a timestamp
within one hour of the search. Events must be received by the insights API within four days of their occurrence.
To summarize, it’s best to send only historical data that occurred within the last four days, with an accurate timestamp
. Then as you begin to send current events to Algolia, there will be a smooth transition once your external historical data ages out.
How to send batched events
You can send events using the API clients or through the REST API directly.
The following snippets handle a specific scenario: an online bookshop that wants to implement Personalization. They want to send historical data they have for each user. The example shows how to send two click events and two conversion events for a user with a userToken
of user-123456
.
Two days ago, this user searched for, viewed, clicked on, and purchased the two latest Harry Potter books. These books have objectIDs
of 9780439784542
and 9780545139700
.
Though these examples show how to batch viewedObjectIds
, clickedObjectIdsAfterSearch
, and convertedObjectIdsAfterSearch
events, you can batch any event type, for example, clickedObjectIds
, convertedObjectIds
, viewedFilters
, clickedFilters
, and convertedFilters
. Rather than using these methods directly, you should make use of the sendEvents
method exposed by all API clients.
Using an API client
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
| $insights = Algolia\AlgoliaSearch\InsightsClient::create(
'YourApplicationID',
'YourSearchOnlyAPIKey'
);
$response = $insights->sendEvents(array(
array(
'eventType' => 'click',
'eventName' => 'Product Clicked',
'index' => 'products',
'userToken' => 'user-123456',
'objectIDs' => array('9780545139700', '9780439784542'),
'timestamp' => 1529055974,
'queryID' => '43b15df305339e827f0ac0bdc5ebcaa7'
),
array(
'eventType' => 'view',
'eventName' => 'Product Detail Page Viewed',
'index' => 'products',
'userToken' => 'user-123456',
'objectIDs' => array('9780545139700', '9780439784542'),
'timestamp' => 1521710906
),
array(
'eventType' => 'conversion',
'eventName' => 'Product Purchased',
'index' => 'products',
'userToken' => 'user-123456',
'objectIDs' => array('9780545139700', '9780439784542'),
'timestamp' => 1529055974,
'queryID' => '43b15df305339e827f0ac0bdc5ebcaa7'
),
));
|
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
| insights = Algolia::Insights::Client.create('YourApplicationID', 'YourSearchOnlyAPIKey')
insights.user('user-123456').send_events(
[
{
eventType: 'click',
eventName: 'Product Clicked',
index: 'products',
userToken: 'user-123456',
timestamp: 1529055974,
objectIDs: ['9780545139700', '9780439784542'],
queryID: '43b15df305339e827f0ac0bdc5ebcaa7',
positions: [7, 6]
},
{
eventType: 'view',
eventName: 'Product Detail Page Viewed',
index: 'products',
userToken: 'user-123456',
timestamp: 1521710906,
objectIDs: ['9780545139700', '9780439784542']
},
{
eventType: 'conversion',
eventName: 'Product Purchased',
index: 'products',
userToken: 'user-123456',
timestamp: 1528364634,
objectIDs: ['9780545139700', '9780439784542'],
queryID: '43b15df305339e827f0ac0bdc5ebcaa7'
}
]
)
|
1
2
| // Use the Insights REST API directly to send batched events
// See https://www.algolia.com/doc/rest-api/insights/#push-events for more information
|
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
| insights = client.init_insights_client().user('user-123456')
insights.send_events(
[
{
"eventType": "click",
"eventName": "Product Clicked",
"index": "products",
"userToken": "user-123456",
"timestamp": 1529055974,
"objectIDs": ["9780545139700", "9780439784542"],
"queryID": "43b15df305339e827f0ac0bdc5ebcaa7",
"positions": [7, 6]
},
{
"eventType": "view",
"eventName":"Product Detail Page Viewed",
"index": "products",
"userToken": "user-123456",
"timestamp": 1521710906,
"objectIDs": ["9780545139700", "9780439784542"]
},
{
"eventType": "conversion",
"eventName": "Product Purchased",
"index": "products",
"userToken": "user-123456",
"timestamp": 1528364634,
"objectIDs": ["9780545139700", "9780439784542"]
"queryID": "43b15df305339e827f0ac0bdc5ebcaa7"
}
]
)
|
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
35
36
| let insightsClient = InsightsClient(appID: "YourApplicationID", apiKey: "YourSearchOnlyAPIKey")
let eventClick: InsightsEvent = .click(name: "Product Clicked",
indexName: "products",
userToken: "user-123456",
queryID: "43b15df305339e827f0ac0bdc5ebcaa7",
objectIDsWithPositions: [
("9780545139700", 7),
("9780439784542", 6)
])
let eventView: InsightsEvent = .view(name: "Product Detail Page Viewed",
indexName: "products",
userToken: "user-123456",
objectIDs: [
"9780545139700",
"9780439784542"
])
let eventConversion: InsightsEvent = .conversion(name: "Product Purchased",
indexName: "products",
userToken: "user-123456",
queryID: "43b15df305339e827f0ac0bdc5ebcaa7",
objectIDs: [
"9780545139700",
"9780439784542"
])
let events = [eventClick, eventView, eventConversion]
insightsClient.sendEvents(events) { result in
if case .success(let response) = result {
print("Response: \(response)")
}
}
|
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
| val insights = ClientInsights(
applicationID = ApplicationID("YourApplicationID"),
apiKey = APIKey("YourSearchOnlyAPIKey")
)
val eventClick = InsightsEvent.Click(
eventName = EventName("Product Clicked"),
indexName = IndexName("products"),
userToken = UserToken("user-123456"),
timestamp = 1529055974L,
queryID = QueryID("43b15df305339e827f0ac0bdc5ebcaa7"),
resources = InsightsEvent.Resources.ObjectIDs(listOf(ObjectID("9780545139700"), ObjectID("9780439784542"))),
positions = listOf(7, 6)
)
val eventView = InsightsEvent.View(
eventName = EventName("Product Detail Page Viewed"),
indexName = IndexName("products"),
userToken = UserToken("user-123456"),
timestamp = 1521710906L,
resources = InsightsEvent.Resources.ObjectIDs(listOf(ObjectID("9780545139700"), ObjectID("9780439784542"))),
)
val eventConversion = InsightsEvent.Conversion(
eventName = EventName("Product Purchased"),
indexName = IndexName("products"),
userToken = UserToken("user-123456"),
timestamp = 1528364634L,
queryID = QueryID("43b15df305339e827f0ac0bdc5ebcaa7"),
resources = InsightsEvent.Resources.ObjectIDs(listOf(ObjectID("9780545139700"), ObjectID("9780439784542"))),
)
insights.sendEvents(events = listOf(eventClick, eventView, eventConversion))
)
|
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
35
| var insights = new InsightsClient(
"YourApplicationID",
"YourSearchOnlyAPIKey"
);
var events = new List<InsightsEvent>(){
new InsightsEvent(
EventType = "click",
UserToken = "user-123456",
EventName = "Product Clicked",
Index = "products",
ObjectIDs = new List<string>{ "9780545139700", "9780439784542" },
Positions = new List<uint> { 17, 19 },
QueryID = "43b15df305339e827f0ac0bdc5ebcaa7",
Timestamp = 1529055974;
),
new InsightsEvent(
EventType = "view",
UserToken = "user-123456",
EventName = "Product Detail Page Viewed",
Index = "products",
ObjectIDs = new List<string>{ "9780545139700", "9780439784542" },
Timestamp = 1521710906;
),
new InsightsEvent(
EventType = "conversion",
UserToken = "user-123456",
EventName = "Product Detail Page Viewed",
Index = "products",
ObjectIDs = new List<string>{ "9780545139700", "9780439784542" },
QueryID = "43b15df305339e827f0ac0bdc5ebcaa7",
)
};
insights.sendEventsAsync(events);
|
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
35
36
37
| InsightsClient insights = DefaultInsightsClient.create(
"YourApplicationID",
"YourSearchOnlyAPIKey"
);
InsightsEvent eventClick =
new InsightsEvent()
.setEventType("click")
.setUserToken("user-123456")
.setEventName("Product Clicked")
.setIndex("products")
.setObjectIDs(Arrays.asList("9780545139700", "9780439784542"))
.setPositions(Arrays.asList(17L,19L))
.setQueryID("43b15df305339e827f0ac0bdc5ebcaa7")
.setTimestamp(1529055974L);
InsightsEvent eventView =
new InsightsEvent()
.setEventType("view")
.setUserToken("user-123456")
.setEventName("Product Detail Page Viewed")
.setIndex("products")
.setObjectIDs(Arrays.asList("9780545139700", "9780439784542"))
.setTimestamp(1521710906L);
InsightsEvent eventConversion =
new InsightsEvent()
.setEventType("conversion")
.setUserToken("user-123456")
.setEventName("Product Purchased")
.setIndex("products")
.setObjectIDs(Arrays.asList("9780545139700", "9780439784542"))
.setQueryID("43b15df305339e827f0ac0bdc5ebcaa7");
List<InsightsEvent> events = Arrays.asList(eventClick, eventView, eventConversion);
insights.sendEventsAsync(events);
);
|
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
| client := insights.NewClient("YourApplicationID", "YourAPIKey")
events := []insights.Event{
{
EventType: "click",
EventName: "Product Clicked",
Index: "products",
UserToken: "user-123456",
Timestamp: time.Unix(1529055974, 0),
ObjectIDs: []string{"9780545139700", "9780439784542"},
Positions: []int{7, 6},
QueryID: "43b15df305339e827f0ac0bdc5ebcaa7"
},
{
EventType: "view",
EventName: "Product Detail Page Viewed",
Index: "products",
UserToken: "user-123456",
Timestamp: time.Unix(1521710906, 0),
ObjectIDs: []string{"9780545139700", "9780439784542"}
},
{
EventType: "conversion",
EventName: "Product Purchased",
Index: "products",
UserToken: "user-123456",
Timestamp: time.Unix(1528364634, 0),
ObjectIDs: []string{"9780545139700", "9780439784542"},
QueryID: "43b15df305339e827f0ac0bdc5ebcaa7"
},
}
res, err := client.SendEvents(events)
|
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
35
| client.execute {
val eventClick = InsightsEvent(
eventType = "click",
eventName = "Product Clicked",
index = "products",
userToken = "user-123456",
objectIDs = Some(Seq("9780545139700", "9780439784542")),
positions = Some(Seq(7, 6)),
queryID = Some("43b15df305339e827f0ac0bdc5ebcaa7"),
timestamp = Some(1529055974L)
)
val eventView = InsightsEvent(
eventType = "view",
eventName = "Product Detail Page Viewed",
index = "products",
userToken = "user-123456",
objectIDs = Some(Seq("9780545139700", "9780439784542")),
timestamp = Some(1521710906L)
)
val eventConversion = InsightsEvent(
eventType = "click",
eventName = "Product Clicked",
index = "products",
userToken = "user-123456",
objectIDs = Some(Seq("9780545139700", "9780439784542")),
positions = Some(Seq(7, 6)),
queryID = Some("43b15df305339e827f0ac0bdc5ebcaa7"),
timestamp = Some(1529055974L)
)
send events Seq(eventClick, eventView, eventConversion)
}
}
|
Using the REST API
If you are using the search-insights library to send events from your implementation, you can only batch historical events by sending them directly to the Insights REST API.
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
35
36
| curl -X POST \
https://insights.algolia.io/1/events \
-H 'x-algolia-api-key: ${ADMIN_API_KEY}' \
-H 'x-algolia-application-id: ${APPLICATION_ID}' \
-H "Content-Type: application/json" \
-d '{
"events": [
{
"eventType": "click",
"eventName": "Product Clicked",
"index": "products",
"userToken": "user-123456",
"timestamp": 1529055974,
"objectIDs": ["9780545139700", "9780439784542"],
"queryID": "43b15df305339e827f0ac0bdc5ebcaa7",
"positions": [7, 6]
},
{
"eventType": "view",
"eventName":"Product Detail Page Viewed",
"index": "products",
"userToken": "user-123456",
"timestamp": 1521710906,
"objectIDs": ["9780545139700", "9780439784542"]
},
{
"eventType": "conversion",
"eventName": "Product Purchased",
"index": "products",
"userToken": "user-123456",
"timestamp": 1528364634,
"objectIDs": ["9780545139700", "9780439784542"],
"queryID": "43b15df305339e827f0ac0bdc5ebcaa7"
}
]
}'
|
When the query is successful, the HTTP response is a 200 OK.
1
2
3
4
| {
"status": 200,
"message": "OK"
}
|
Insights events (view, click, and conversion) don’t take immediate effect. The delay can range from a few minutes to an hour, depending on whether they are sent after a search or not, and how long after a search they are sent. For precise timeframes, see our page on when Insights events take effect.