Before you start:
If you are new to PosNeg tracking we recommend reading our introduction which can be found here https://docs.sajari.com/user-guide/analytics/posneg-tracking/
Advanced Tracking
PosNeg tracking provides flexible tracking tokens which can be used in a variety of use-cases to provide both useful analytics and to feed search.io’s machine learning algorithms data about the performance of search results.
Generating PosNeg tokens
PosNeg tokens are generated by adding a tracking object when Querying a collection https://docs.sajari.com/api/#operation/QueryCollection. Within the tracking object type
must be set to “POS_NEG"
, query_id
must be assigned a unique identifier (more on this later), and field
must be passed the field name which contains the unique identifier you have assigned to each record i.e. a product ID may be appropriate for ecommerce scenarios.
{ "variables": { "q" : "samsung tv" }, "tracking": { "type": "POS_NEG", "query_id": "4216691599", "field": "productId" } } }
The API response will contain PosNeg tokens for each search result. Each token allows us to tie an interaction back to a specific query.
{ "results": [ { "record": { "productId": "5577783", "name": "Samsung LED TV" }, "token": { "pos_neg": { "pos": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwdXJwb3NlIjoicG9zIiwiZGVzdGluYXRpb24iOiIiLCJ2YWxzIjp7ImNvbGxlY3Rpb24iOlsiYmVzdGJ1eSJdLCJjb21wYW55IjpbIjE1OTQxNTM3MTE5MDE3MjQyMjAiXSwiZmllbGQiOlsiaWQiXSwicHJvamVjdCI6WyIxNTk0MTUzNzExOTAxNzI0MjIwIl0sInEuaWQiOlsiNDIxNjY5MTU5OSJdLCJxLnNsIjpbIjEiXSwicS51aWQiOlsiNDIxNjY5MTU5OTEiXSwidmFsdWUiOlsiNTU3Nzc4MyJdfX0.5KKsQaXG1b6LaDwkaTh9tpSAJONFY3nbSj4ZJYJM1IM", "neg": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwdXJwb3NlIjoibmVnIiwiZGVzdGluYXRpb24iOiIiLCJ2YWxzIjp7ImNvbGxlY3Rpb24iOlsiYmVzdGJ1eSJdLCJjb21wYW55IjpbIjE1OTQxNTM3MTE5MDE3MjQyMjAiXSwiZmllbGQiOlsiaWQiXSwicHJvamVjdCI6WyIxNTk0MTUzNzExOTAxNzI0MjIwIl0sInEuaWQiOlsiNDIxNjY5MTU5OSJdLCJxLnNsIjpbIjEiXSwicS51aWQiOlsiNDIxNjY5MTU5OTEiXSwidmFsdWUiOlsiNTU3Nzc4MyJdfX0.QraRedkZhcEAFwrAA90Rd63DCD3eKPtbL1JrKnMkbkY" } } }, { "record": { "productId": "5042100", "name": "Samsung - LED - 2160p - Smart - 4K }, "token": { "pos_neg": { "pos": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwdXJwb3NlIjoicG9zIiwiZGVzdGluYXRpb24iOiIiLCJ2YWxzIjp7ImNvbGxlY3Rpb24iOlsiYmVzdGJ1eSJdLCJjb21wYW55IjpbIjE1OTQxNTM3MTE5MDE3MjQyMjAiXSwiZmllbGQiOlsiaWQiXSwicHJvamVjdCI6WyIxNTk0MTUzNzExOTAxNzI0MjIwIl0sInEuaWQiOlsiNDIxNjY5MTU5OSJdLCJxLnNsIjpbIjIiXSwicS51aWQiOlsiNDIxNjY5MTU5OTEiXSwidmFsdWUiOlsiNTA0MjEwMCJdfX0.JkAbTpQ0XiDbHxanLQOLv5niMwu6QT8L1BmbAromMjs", "neg": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwdXJwb3NlIjoibmVnIiwiZGVzdGluYXRpb24iOiIiLCJ2YWxzIjp7ImNvbGxlY3Rpb24iOlsiYmVzdGJ1eSJdLCJjb21wYW55IjpbIjE1OTQxNTM3MTE5MDE3MjQyMjAiXSwiZmllbGQiOlsiaWQiXSwicHJvamVjdCI6WyIxNTk0MTUzNzExOTAxNzI0MjIwIl0sInEuaWQiOlsiNDIxNjY5MTU5OSJdLCJxLnNsIjpbIjIiXSwicS51aWQiOlsiNDIxNjY5MTU5OTEiXSwidmFsdWUiOlsiNTA0MjEwMCJdfX0.qhyTVZOWzeWzTmolyaMxsmMz1yHQySeoQc-S9PIfEBc" } } } ] }
Search sessions:
A search from an end user perspective is often more than the action of typing text into a search bar. It can become a sequence of actions where the user reaches a refined set of search results. Actions such as refining by a product size, price range, stock availability or tweaking the search text. These combined interactions are what we refer to as a search session.
PosNeg tracking requires customers who are using our API to define and manage the state of their own search sessions. If you would prefer session handling to be managed for you then take a look at our UI libraries https://docs.sajari.com/developer-guide/api/api-clients/ .
Why is it important to define the search session?
Defining a search session provides a fuller picture of search performance and enriches the quality of the data used for machine learning and business analysis.
Here are some recommended events to define a new search session:
The query text has been cleared after being non-empty i.e. from a delete
The first 3 characters of the query text have changed i.e. from direct replacement
The previous search returned no results
Actions that don’t meet the one of above would be considered part of the same search session.
How to manage sessions:
New sessions are defined by simply passing a new unique identifier to our query_id
parameter when using the the Query collection call i.e. query_id: "4216691599"
.
If you already have independent session logic in place these ID’s may also be suitable to use for query_id
When querying the collection as part of the same session the sequence
field must be incremented.
Session and sequence information is automatically encoded into the PosNeg tokens
Session Example:
A user starts a new search session by typing “Samsung TV” into the search bar. Below is an example the Query collection call where query_id
must be passed a unique ID and sequence
set to 0
{ "variables": { "q" : "samsung tv" }, "tracking": { "type": "POS_NEG", "query_id": "4216691599", "sequence": 0, "field": "productId" } }
The user then adds a price filter. As this is the same session the the Query collection call should contain the same query_id
whilst the sequence
is incremented to 1
{ "variables": { "q" : "samsung tv" }, "tracking": { "type": "POS_NEG", "filter": price < 1000, "query_id": "4216691599", "sequence": 1, "field": "productId" } }
The user then searches for “tv cabinet”. This should be treated as a new session so the the Query collection call should contain a new unique query_id
and sequence
should be reset to 0.
{ "variables": { "q" : "tv cabinet" }, "tracking": { "type": "POS_NEG", "query_id": "5643627563", "sequence": 0, "field": "id" } }
Storing and sending tokens back
PosNeg tokens can be used more than once. This means that a single token can be used to send positive signals as a user moves through a funnel. Additionally, tokens can be stored for long durations in order to attribute search queries with results even over long session times. For example, if a user performs a search and finds a good result but doesn't actually purchase the product until much later.
Tokens can be stored using standard methods such as cookies, localStorage or cached server side.
When an event occurs like a user clicking a search result the token associated with the record for that specific search result should be sent using the API SendEvent https://docs.sajari.com/api/#operation/SendEvent
An appropriate name such as ‘click’ should be assigned to the name
field. metadata
and weight
do not need to be defined and are not in scope for this guide.
{ "name": "click", "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwdXJwb3NlIjoicG9zIiwiZGVzdGluYXRpb24iOiIiLCJ2YWxzIjp7ImNvbGxlY3Rpb24iOlsiYmVzdGJ1eSJdLCJjb21wYW55IjpbIjE1OTQxNTM3MTE5MDE3MjQyMjAiXSwiZmllbGQiOlsiaWQiXSwicHJvamVjdCI6WyIxNTk0MTUzNzExOTAxNzI0MjIwIl0sInEuaWQiOlsiNDIxNjY5MTU5OSJdLCJxLnNsIjpbIjEiXSwicS51aWQiOlsiNDIxNjY5MTU5OTEiXSwidmFsdWUiOlsiNTU3Nzc4MyJdfX0.5KKsQaXG1b6LaDwkaTh9tpSAJONFY3nbSj4ZJYJM1IM" }
If the user then purchases the product the same token should be sent with another API SendEvent call, but this time with a new name
.
{ "name": "purchase", "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwdXJwb3NlIjoicG9zIiwiZGVzdGluYXRpb24iOiIiLCJ2YWxzIjp7ImNvbGxlY3Rpb24iOlsiYmVzdGJ1eSJdLCJjb21wYW55IjpbIjE1OTQxNTM3MTE5MDE3MjQyMjAiXSwiZmllbGQiOlsiaWQiXSwicHJvamVjdCI6WyIxNTk0MTUzNzExOTAxNzI0MjIwIl0sInEuaWQiOlsiNDIxNjY5MTU5OSJdLCJxLnNsIjpbIjEiXSwicS51aWQiOlsiNDIxNjY5MTU5OTEiXSwidmFsdWUiOlsiNTU3Nzc4MyJdfX0.5KKsQaXG1b6LaDwkaTh9tpSAJONFY3nbSj4ZJYJM1IM" }
A user may have multiple products each with a token from different search sessions in their basket. On purchase the tokens must all be sent individually via API SendEvent.
For ecommerce we recommend tracking just click and purchases to start until you have a picture of how machine learning is impacting performance. Then fine tune by adding further events/stages of the funnel such as basket etc.
What do I do with neg tokens?
You only need to to return neg tokens where the user has taken a specific negative action e.g. down voting an item, marking a result as unhelpful etc.
Sajari automatically handles negatives in scenarios such as a user not interacting with any search results, or passing over higher ranked results to click on a lower ranked result.
Leveraging machine learning
Now you’ve implemented PosNeg tracking hop over to our guide on Dynamic Boosting so you can start leveraging machine learning! https://docs.sajari.com/user-guide/relevance-tuning/dynamic-boosting/