Monitor Azure Search With Azure Application Insights

In my last post, Add Search to Hugo Sites With Azure Search, I explained how I added a search capability to my site using Azure Search. In this post, I’ll show you how I monitor it to see what queries people are running and which result they are clicking on.

Using Azure Application Insights, and the optional PowerBI Content Pack provided by Microsoft, you can get some cool insights into your search implementation. What I’ve done is hook it up so every time search is executed on my site, I track it, as well as which item in the results people clicked on.

Here’s what it looks like in my Azure App Insights instance for my site when I search for all events that start with search/:

Azure App Insights Search Results

Azure App Insights Search Results

The first column shows the results of filtering all custom events that start with search/. Notice there are two types of events: search/execute & search/result_click:

Azure App Insights - Event List

Azure App Insights - Event List

When I select one of these, it shows complete timeline for this user’s session:

Azure App Insights - Session Timeline

Azure App Insights - Session Timeline

From here, I can can see what page they were on but also that they executed a search query and also clicked on one of the results. If I select the search/execute entry, you can see the details of the query:

Azure App Insights - Search Execute Details

Azure App Insights - Search Execute Details

The notable details from this image are the QueryTerms, what they searched for, and the SearchId. Each search query has an ID that you can lookup later to see what results they got back.

If I select the search/result_click, you can see which item they clicked:

Azure App Insights - Search Result Click Details

Azure App Insights - Search Result Click Details

Here you can see the user clicked the 2nd item in the results. You also have the ID of the document as in the search index as well as the ID of the search query. You can use these within the PowerBI report. To learn more about the PowerBI report, select the menu item Search traffic analytics in your Azure Search instance located in the Azure portal.

For the remainder of this post, I’ll show you how I set this up on my site.

Configure the search query & returned results

I’m going to assume you already have Azure Application Insights set up on your site. If you don’t, that’s the first step.

Next, you need to make some changes to how you execute the query to ask Azure Search to include the ID of the search query in the returned results. You do this by adding a few HTTP headers to the request. Then, when you get the results, fetch the ID of the search query out of the response’s HTTP header and stuff it into a variable an log the custom event to App Insights:

<script>
// existing code to configure & parse mustache template & get all search parameters

// add headers to the request to ask for the search ID
$.ajax({
  url: 'https://' + azSearchInstance + '.search.windows.net/indexes/' + azSearchIndex
    + '/docs?api-version=2019-05-06&$top=' + azSearchResults
    + '&api-key=' + azApiKey + '&search=' + encodedQuery,
  method: 'GET',
  headers: {
    'x-ms-azs-return-searchid': 'true',
    'Access-Control-Expose-Headers': 'x-ms-azs-searchid'
  }
}).done(function (data, responseText, jqXHR) {
  // update the result set to give each an index
  // there's other ways to do this with mustache, but this is easier :)
  var index = 1;
  for (i = 0; i < data.value.length; i++) {
    data.value[i].index = index++;
  }

  // display results
  var render = Mustache.render(template, data);
  $(".container .search-results").html(render)

  // get search id
  azureSearchId = jqXHR.getResponseHeader('x-ms-azs-searchid');

  // track search event
  appInsights.trackEvent("search/execute", {
    SearchServiceName: azSearchInstance,
    SearchId: azureSearchId,
    IndexName: azSearchIndex,
    QueryTerms: query,
    ResultCount: azSearchResults,
    ScoringProfile: 'default'
  });
});
</script>

I also modified the search results to add an index to each of the items in the returned result collection. Why? Because I want to track which item in the index someone selected. Let’s say if I get a lot of queries for “SPFx Web Parts” and most people are selecting the 4th item in the results, that tells me I need to make this page more visible in the results and possibly promote it to the top and highlight it on the site.

There are ways with Mustache to get the index of an item in a collection, but I found this to be easier. Looping through 25 items on the page isn’t expensive, so I went with the easier approach.

Update rendered search results

Next, I need to update how the results are rendered and create a new function that will log a custom event to App Insights on each result click:

<h2>
  <a href="[[ url ]]"
     onClick="trackSearchClick([[ index ]], '[[ AzureSearch_DocumentKey ]]')">
    [[ title ]]
  </a>
</h2>

<script>
// add this outside the IIFE (function(){})()
var azureSearchId = '';

function trackSearchClick(index, docId) {
  appInsights.trackEvent("search/result_click", {
    SearchServiceName: '{{ .Site.Params.azureSearchInstance }}',
    SearchId: azureSearchId,
    ClickedDocId: docId,
    Rank: index,
    TargetPageTitle: this.event.target.innerText,
    TargetPageUrl: this.event.target.href
  });
}
</script>

Here, I modified the link to the item in the results to call a method trackSearchClick() and I pass in the document’s ID and index. This is how I’m logging each time someone clicks on a search result.

That’s pretty much it! There’s just one more step to finishing off my search implementation, and that’s to trigger a reindex each time the site is updated. That’s in the next post.

Andrew Connell
Developer & Chief Course Artisan, Voitanos LLC. | Microsoft MVP
Written by Andrew Connell

Andrew Connell is a full stack developer who focuses on Microsoft Azure & Microsoft 365. He’s a 20+ year recipient of Microsoft’s MVP award and has helped thousands of developers through the various courses he’s authored & taught. Andrew’s mission is to help web developers become experts in the Microsoft 365 ecosystem, so they can become irreplaceable in their organization.

Share & Comment