Learn to Rank
Learn to Rank is a machine learning technique that allows you to train a model to rank search results. The model is trained using a set of features and a set of relevance judgements. The model is then used to rank search results.
In this guide, you will learn how to integrate Learn to Rank with Metarank and Searchkit. You can learn more about Learn to Rank with Metarank in the Metarank documentation (opens in a new tab).
We assume in this guide that you have:
- Installed Metarank and Searchkit
- Trained a model using Metarank
- Setup the features and relevance judgements for your model
Changes to Searchkit UI
Metarank requires session id and user id to be sent with each search request. One way to do this is in the @searchkit/instantsearch-client
and provide the session id and user id via headers:
const searchClient = Client({
url: "/api/search",
headers: {
"x-session-id": "my-session-id",
"x-user-id": "my-user-id",
},
});
Changes to the Searchkit API
To integrate Learn to Rank with Searchkit, we will use the hooks for beforeSearch
and afterSearch
. These hooks allow us to modify the query and the results before they are sent to Elasticsearch and returned to the UI.
We will use the afterSearch
hook to send the results to the Metarank API and update the results with the new order.
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
const headers = req.headers
const results = await client.handleRequest(req.body, {
hooks: {
afterSearch: async (searchRequests, searchResponses) => {
// Get the first search request
const [uiRequest, otherRequests] = searchRequests;
// Get the first search response
const [uiResponse, otherResponses] = searchResponses;
// Get the session id and user id from the headers
const sessionId = headers["x-session-id"];
const userId = headers["x-user-id"];
// Get the query from the first search request
const query = uiRequest.body.query;
// Get the results from the first search response
const results = uiResponse.body.hits.hits;
// Send the request to the Metarank API
const response = await fetch("http://localhost:8080/rank/xgboost", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
session: sessionId,
user: userId,
fields: [
{ name: "query", value: query }
],
timestamp: (new Date()).getTime(),
items: results.map((item) => {
return {
id: item._id,
// an optional array of extra fields that you can use in your model
fields: [
{ name: "title", value: item._source.title },
{ name: "description", value: item._source.description },
{ name: "url", value: item._source.url },
],
};
}})
}),
});
// Get the response from the Metarank API
const metarankResponse = await response.json();
// Get the items order from the response
const items = metarankResponse.items;
// Update the order of the results for the first 20 results
const updatedResults = items.map((item) => {
const result = results.find((result) => result._id === item.id);
return result
});
// Update the results in the first search response
const updatedUiResponse = {
...uiResponse,
body: {
...uiResponse.body,
hits: {
...uiResponse.body.hits,
hits: updatedResults,
},
},
};
return [
updatedUiResponse,
...otherResponses
];
}
}
});
}