The search query is denied because it originated from a Coveo quick view

A few months ago I was troubleshooting an issue with a failing Coveo index rebuild. Several times, while reviewing the Sitecore logs, I noticed an error occurring very frequently (~250k times in one log file) after the index rebuild process had started:

WARN  The search query is denied because it originated from a Coveo quick view. For more information, enable DEBUG logging for the 'Coveo.SearchProvider.LinqToCoveoIndex`1[TItem]' class.

I put this error message into Google only to find absolutely nothing. Our search page wasn’t even using quick views, so why was this error showing up in the logs? I enabled DEBUG logging but was not able to find a cause of the error. I contacted Coveo Support.

Wait… What is a Quick View Anyway?

Basically it’s a feature of Coveo that lets you preview a page in the index, quickly. You can read more about it here. Even if you aren’t using quick views on your search page, Coveo still uses and renders them. For example, if you open an indexed item’s properties in the Content Browser in Coveo Cloud, you will see a quick view tab. Upon opening that tab, Coveo generates a preview of your page. It’s much like opening the page manually in a browser, except the page renders much faster in a quick view.

Understanding the Issue

When a Coveo index is rebuilding, Coveo visits the item to fill its quick view. If Coveo is visiting a page where you have a very complex component or module running, that might prompt this error to occur. For example, in my client’s site they have a component named Related Articles, which basically shows a list of other articles that are related to this one. This site happened to have hundreds of thousands of articles, all which needed to be indexed, so the Coveo crawler was hitting these articles and their related articles over and over again.

Solutions

Coveo Support provided an article with a potential solution. Apparently, adding a Request.UserAgent check in complex components on indexed pages is one option. This can be placed on a view, model or sublayout, as the article states, but I also found out that you can add it to your back end code, too; and in my case, that seemed like the best thing to do. In the code that gets the related articles, I put this in at the very beginning of the method:

    if (HttpContext.Current != null && HttpContext.Current.Request != null && HttpContext.Current.Request
        .UserAgent.Contains("Coveo Sitecore Search Provider"))
    {
        return null;
    }

After rebuilding the indexes, the quick view warning was suddenly gone.

Another option Coveo provided was to disable queries from quick views completely. You could add the code in Step 1 of this article to your custom search provider config, but supply a value of false. As the document states,

This setting acts as a master switch. If the setting is set to false, the search queries are never executed in the context of the quick view.

Conclusion

The point is, if you have any complex logic running on a page you know you are indexing, you need to handle that via one of the two above solutions. This could speed up your rebuild time too.

Advertisements

Creating a Custom Facet in Coveo Hive – Part Three

This is the 3rd (and most likely final) blog post in the Creating a Custom Facet in Coveo Hive series. If you’ve completed parts one and two, you’ve got a working custom facet that can be interacted with and can modify the current query and state, and update the search results that appear on the page. The last big piece of functionality, in my opinion, is setting up the facet breadcrumbs. This step is totally optional, and you should check with project management to make sure it falls within scope and the client requested to implement.

I struggled on this piece greatly because I wasn’t able to find any documentation on how to do this for a custom (Hive) facet. I had to contact Coveo Support, who then referred me to a Typescript file in their GitHub repositories which had the code for setting up breadcrumbs (albeit in a language I wasn’t too familiar with). I didn’t quite understand how the code worked, even after getting past the language barriers, and I wasn’t sure which parts I actually needed in my code. Thus, I created this blog post to answer some of those questions, for those that are in my same shoes at some point in the future.

What Functionality Do We Need?

Before thinking about exactly what code is required to implement breadcrumbs, it may help to think about what our goals are, on a high level. If you are unfamiliar with Coveo breadcrumbs, they are pieces of markup that are generated and added to the DOM when a Coveo facet value changes (an option is checked, a value is submitted, etc). By default they appear above the search results. This is often termed the “breadcrumb bar”.

breadcrumb bar

Continue reading “Creating a Custom Facet in Coveo Hive – Part Three”

Creating a Custom Facet in Coveo Hive – Part Two

In my previous blog post, I went over the basics of what I needed to do to set up a custom facet / component in Coveo Hive. In this blog post, I will take a deeper dive into how we can have our custom facet interact with the current Coveo query on the search page and manage Coveo state. Let’s get started.

Updating the Current Coveo Query

At this point, you should have a visible and interact-able facet. When a user enters a value into a field of your facet, checks a box, or makes some other type of facet interaction, you’ll want to make sure the Coveo search page reflects this interaction by showing updated search results. In technical terms, we can achieve this by adding our custom facet interactions to the advanced expression of the current query. We will need to do the following:

  1. Add code to process the query change.
    1. Update the Coveo state.
    2. Then, call executeQuery() to run the buildingQuery event, which will set the advanced expression and cause the search results component to refresh.
    3. Finally, log the search event to Coveo Usage Analytics (optional).

Continue reading “Creating a Custom Facet in Coveo Hive – Part Two”

Creating a Custom Facet in Coveo Hive – Part One

Recently I was tasked with creating a custom facet for a client’s Coveo for Sitecore implementation. I was implementing Coveo Hive, which worked well and it was very simple to add components to the page in a modularized fashion. After reviewing the proof of concept search page, the client realized they didn’t like the date slider component at all, and asked that we instead have a facet with two fields, start date and end date, and each field would have a calendar picker.

I quickly found out this was not available as an OOTB component. I would have to learn how to create a custom component and allow it to be added to a search page. I would have to manage state, facet appearance and breadcrumbs for the new facet. Due to the complexity of this task, I will be creating a blog post series for each major part. In this first blog post, I will go through the basic setup of your custom facet and at the end of this post, you should be able to see and interact with your facet to some extent. Final code will be provided at the end of the final blog post in this series. Let’s get started!

It Starts With Javascript (Or Typescript)

When I first started working on this, Coveo’s documentation suggested creating a custom component using Javascript. It looks like they’ve updated their documentation. You’ll want to start here and pick one of the two paths. I went the JS path, so my code will be different from yours if you choose the TS path.

Continue reading “Creating a Custom Facet in Coveo Hive – Part One”

The coveo-facet-empty class

Recently I struggled through the creation of a custom component in Coveo Hive. My goal was to create a custom facet with two fields, start and end date, and get results to filter based on selections in those dropdowns, include breadcrumbs, etc. One issue that I ran into time and time again was my facet not appearing in the facets section. At first I thought the markup simply wasn’t generated, until I inspected the DOM and found it was there, but hidden.

 id="_..." class="CoveoFacet coveo-facet-empty"

I could immediately tell it was empty due to the existence of the coveo-facet-empty class (it makes sense), but I didn’t manually add this class. It turns out Coveo adds this class to any facet, but only for certain conditions:

  • The facet is not pointing to a field where it can get data, or the field simply has no data for ANY of the search results. This was not my problem.
  • The facet’s isFacet setting is set to false. Okay, so this one actually got me once – for some reason, my facet had the setting equal to false. It needed to be true, so I set it to true in the Cloud Platform -> Fields page, and the facet showed up. Later that week though, the facet disappeared again – so keep reading.
  • There is a syntactical error in the Javascript of your custom component. This happened to me several times. The console should explain what the issue is. Usually I was missing a curly bracket or something minute like that.

Hope this helps anyone having the same issue.