Duplicate Facet Value Coveo Dynamic Hierarchical Facet

Recently I bumped in to this issue escalated from our client side. It seemed although ML models are working way too hard. This is my first experience with Dynamic Navigation Coveo ML model which promises to understand what Facet values and Facets are important based on Analytics data captured. It comes in especially handy for top Facets that are frequently used or expected to be used on search page by most users to drill down to their search results.

We were using Coveo Dynamic Category Facet. As always Coveo does excellent job at documenting what this facet is all about and how you can configure it on Coveo for Sitecore. In our case, it was Coveo for Sitecore SXA. You can read more about this facet here.

Now working with Coveo Hive components all these years, I was 100% confident that I did not mess anything in there when the issue was brought to my attention. So, I decided since I am in fairly new territory with DNE ML model, I tried dropping that to see if issue disappears and yep it did indeed.

So, isolation is done, ML model is injecting that duplicate value, now the question really becomes why? Next step like always in debug mode of self, let us create a dummy page with a facet based on field of concern and reproduce on cloud search page. Did exactly that with help of Coveo technical contact and to our surprise, the duplicate value issue was not reproducible on cloud hosted search page on same facet type and same facet field with same ML model that was causing this issue on Coveo for Sitecore search page.

Hmmm??? Brain is going wild now? What could be it. It does not seem like ML model data is incorrect based on no replication scenario I explained above and neither seems to be index issue because well facet values on facet look just fine minus ML model. I was so confused!

I noticed that in debug mode, I saw ranking expressions being injected which definitely seems to be the culprit, but, was not sure why. Below is how ranking expressions looked like.

I started digging deep on something that I was hyper confident on – data source – piece by piece. Below highlighted caught my eye for sure.

Delimiting character can be different per Facet Datasource

I decided not to share my hunch with Coveo support team. I have tried sharing my hunches in the past with Coveo and Sitecore team on support issues and that ends up putting us usually on a different path may be because my hunches are not always the right ones. I usually try not to put words/thoughts on to some one who is looking at the problem to understand their perspective and fresh set of eyes with no pre conceived opinions. 🙂

I patiently waited for Coveo to get back to me on this issue I logged since I was going no where with issue on hand. They said the same thing that they were worried about the custom delimiter. To ensure ML model does not throw fits, we had to pass some custom advanced parameters on DNE ML Model. I added below to the model and voila…. No more dups. 🙂

 "commandLineParameters": ["--conf", "coveo.drill.hierarchicalFacetSeparator=:"  ] 

This got me super curious and I wanted to see what else you can do in advanced parameters on ML model. Here is gold mine of good amount of samples. Funny news is none of the examples here could have solved our issue. Coveo promised they will update the documentation to reflect this hiccup. All set and ironed out!

I almost did a party dance. This resolve has gotten us the feature complete sign off. We are set to go live next week. Super excited!

Thanks to Coveo support team who really helped us get over this hump .

Coveo SXA Facet Responsiveness

On recent adventure with latest and greatest of Coveo for Sitecore version as soon as we put together a dummy page to add couple OOTB Coveo components. We immediately noted that on mobile mode the facets were not grouping behind this button called ‘filters’ like it typically does on Coveo installations.

My first guess after looking at few things and trying to ensure I followed all the instructions provided in terms of placeholder hierarchy to follow to inject a Coveo Dynamic Facet is it has to do with SXA usage instead of native MVC Coveo for Hive renderings. Since Coveo mentioned many clients out there have used SXA, we were not worried to leverage SXA as that is direction on the instance we were working with.

I tried couple different things –

Placeholder hierarchy expected for

When none of the above worked it was time to loop in Coveo team for their input as this should work OOTB. I logged this Q&A on Coveo Connect and collaborated directly with my Technical Architect of Coveo and voila they suggested a very nice work around and Facets now collapse behind ‘Filters’ button and our team is super happy as we can focus more on data/content/index/relevancy instead of UI aspect that should be working with Coveo Platform.

Thank you Coveo team for your prompt responsiveness like always. Here is the link that has the concern and solution for those who stumble upon this issue. Hope this helps!

https://connect.coveo.com/s/question/0D76Q00000Cpeek/detail?s1oid=00D3000000007r2&s1nid=0DB0d000000fxdx&emkind=chatterCommentNotification&emvtk=2tNYr4lOQ.xL_jZ5HmzKHjjYk6gg8Nd7wO1ytVlSoEY%3D&s1uid=00532000006Jmya&emtm=1629724236181&fromEmail=1&s1ext=0

In a nut shell, we got to add coveo-facet-column to Sitecore column that contains Coveo facets.

New Search Experience New Challenges

If you think you have seen it all using a specific technology such as Coveo on your Sitecore implementation, think again. Every implementation is different, every client is unique and every challenge YES is a special beast. 🙂

With this brand new Coveo implementation we just delivered in two important phases had its own set of problems we had battle and solve. In this post I want to share a snippet of each and how we tackled each of it.

  1. Sitecore Architecture Limitation/s: When you are adding another layer of implementation on top of stood up system there is always challenges. It depends on how Sitecore was built. Was it built with Experience editor working correctly. Latest versions of Coveo highly depends on this assumption. We had similar issue on this, so, we created a content item added all presentation components we need and copied the presentation over to standard values of concern. We had another issue to battle, Requirement was to show some Sitecore items on Coveo Interfaces as results, but…They don’t have presentation and hence no Link or what so ever. We had to add a pipeline to make that happen and generate apt URL for these items that we want to send the user to.
    We injected a new processor that would generate the URL of specific items in coveoPostItemProcessingPipeline section. Index was now showing up with all the correct URL’s
  2. Variant Implementation : Like with most of commerce implementations, we had what were called base products and variants under each base products. We wanted to showcase variants as beautiful swatches that end user can explore if they are interested. For this client, it was very important to show special variant when a special property was selected from Facet available. To make this happen which data should be tied to index on which type of item was very important to analyse and acted upon based on experience that we were after. After that, it was pretty straightforward to implement variants leveraging grouping on Coveo Query Pipelines.
  3. Price Filter Issues : So, again, every customer wants their Price look and behave differently. Some like Slider, Some like Range and in our case it was just basically a string. This was done to adhere to their original implementation which they like. But, since it was multi language and multi site we ran in to challenges on how to have different fields on Index and how to use the different ones per language/site per context. This is because same field for all currencies would pull incorrect values as Facet Options.
    As a workaround, we loaded which field to Facet on based on Context. This resolved our issue of inconsistent values displayed on Facet. Another issue we faced is Custom Sort, since it is string it was hard to make Custom Sort work through Data Attributes on Coveo Rendering properties. We had do a patch on Javascript side on event preprocessResults to make this requirement meet. It has an object called groupByResults which can be modified to achieve specific order we need.

There were some more interesting challenges we encountered while deploying and testing post Go Live, I will cover those in my next blog. 🙂

When Performance is a Lock

Lock

Performance is usually on back of mind when I do typical chores of a Lead/Architect on any project. Unfortunately, with tighter timelines and supreme focus on getting the tasks done with out even us realizing if often takes a back seat. But, we all need to strive for excellence and the only way you would be able to deliver a quality solution is with a legit key if performance were a lock. 🙂

Performance has that good spot on a quality solution checklist as none of the users like waiting in this fast pace world. I was taking a look back in my blogging and found this one here where I wrote my heart out on some tips that can improve your Sitecore solution in general, this time around I will be adding some personal learning on this current Coveo for Sitecore I am part of where performance is a lock 😉 and in my quest to find a key, I actually found a bunch of things you could do to top off what I already knew. Again, thanks to awesome @Coveo team who always supports the goals and challenges of the integration project and trust me they are never the same, with a different client comes different set of challenges. But, that is the fun right?

Now, enough of the story, lets jump right in to the details. I do not like to repeat what Coveo already recommends, so, I will point you all to right resources where I can.

  1. Case 1: When what you have on Sitecore is simply not enough!
    You have couple of options here to battle this. Which path you would choose usually depends on type of data that you are after. What is the latency tolerance on the piece of data? Is context involved? Do we fetch from third party or is it drawn from business logic based on existing data on your sitecore? When you answer these you could pick the option right that would actually affect your performance in a good, bad or ugly way depending on what you choose.
    If the additional information is user context driven then the processor Coveo offers is way to go. You can find more information here
    If you can live with latency or is tolerable and logic is quite complicated to place in processor noted above, then, computed fields is way to go. You can read more information here, this usually comes with an additional step to ensure your data is fresh especially if your computed fields are drawn from a third party source as Sitecore publish might not refresh some of your data. The additional step is to actually rebuild a specific area of your content tree in a scheduled manner. With Coveo 5, you can use the Index API and fire a special crawler. See more info here, do not forget to configure your new crawler first to keep the scope to what you care about as we all know indexing is a quite expensive operation. If you did not know how to, here is the link to do the same.
    So, choose your path wisely and that will put rest of performance in check.
  2. Case 2: So, yeah, you cant show everything
    This is like almost always right? There is bunch of content on Index, but, we cant show everything in every case. May be some items are only for special group of users or may be we want to show only content items of specific template. I did this like so many times in the past, but, never looked at it from performance lens, when Coveo mentioned we could improve performance with some simple configuration settings on the filters we plan to use, it made be re-read this document here to find what I just skimmed through in my last read. There are so many good/easy settings you can use to improve performance on these filters. Read more here
  3. Case 3: Oh boy, you have loads of data on Index
    I guess any enterprise Sitecore solution would have ton of content, but, we do not want all of it on Coveo Indexes, when you think about it, what you would show on Coveo search interface to user would need to be a page, so, why bother pushing items to index that do not have presentation, right? In most cases that is true unless you have a very different content strategy and link modifications on Sitecore, in these cases we cant exclude all items minus presentation as a default. You can read how to do this here
    In our case, we could not do this, so, had to clean up some not needed data on Index via inclusion/exclusion rules of templates. You can read more about this here

    As we roll along with implementation, I am sure we will learn more and more ways that Coveo provides to keep the performance in check. Again, it was so greatly satisfying to keep learning new things with every implementation. Hope this helps some one who is looking for more ways to enhance performance of their Coveo for Sitecore implementation. This is just a scratch on surface per me, what I would recommend is to work with Coveo team for project specific tricks you could do to ensure Coveo works and behaves as cool as it should be.

See the magic – Coveo Recommendations

If you have not gotten a chance to review my other posts that I wrote up based on our experience implementing Coveo recommendations from the scratch, I would strongly advise going through them first.

Post 1 – Was all about visual clues

Post 2 – The real deal

In this post, now that we have gotten all the set up done, I will focus on how to actually get some recommendations to show up to ensure we apply styles, test the filters out and basically yeah see a working version of recommendations. It was not actually that straight forward, but, thanks to couple hands and also huge thank you to @vbernard to help give some awesome tips that helped us force recommendations when everything else failed.

First, when we have the rendering up on the presentation on all our product detail templates where we wanted to show recommendations from Coveo, we started by visiting lot of pages that made sense to the user flow. I had couple of hands, no kidding here, so, basically I read few posts to understand how Coveo recommendations work internally, though it is a black box, it is fairly easy to understand the basic logic behind how it works. So, we attacked it in such a way that it is bent to give us some results.

This is what we did and it worked on our lower environment and started sending recommendations back, you can also choose to use your QA to fire off some tests and automated requests to do the same. We did a bit of both actually – manual go to set of links that emulated various levels of our product pages and an automated hit to several urls as well.

In a nut shell, Coveo recommendations looks for patterns based on history of the end user and suggests what might interest the user next based on the history and matches that it can find from the recommendations model. It is also important to ensure recommendations model has enough data by adjusting the training settings on the ML model. We tried couple different settings there and rebuilding the model after we visited bunch of pages, circling around the products we care about. Finally! We see the below on our recommendations component

We got lucky to be able to test this on lower environments due to multiple hands and effort by the team to emulate what we could, so, we can test it thoroughly with filters on hand. Oh! In regards to filters, we actually needed lot of context based filters, so, we approached this in two fold process –

  1. Adding a processor via config to coveoProcessParsedRestResponse, this essentially would add in some additional meta data per result that we need for queries and filters. There is some real good example and documentation loaded here . We followed similar path, but, added our own business logic to load context data needed on our filters
  2. Next up, we added a JS query filter as documented here and used a bunch of expression builders based on all the data we loaded either on processor or via the recommendations view such as current item ID or some miscellaneous information we needed per business requirements on what to show on recommendations and what not to.

Now, I am a true believer of back up plans, if our hardwork to emulate and get the recommendations engine to send us a few recommendations had failed, then, we would have applied styles and do other tests via a hack provided to us by @vbernard from Coveo. Here are the steps to make that work:

Step 1: Add a new pipeline

Step 2: Push some featured results to this pipeline

Ignore the cool stones and take a peek at the featured results

Step 3 : Now go back to ML models and add a recommendations model

Thats it! You should now see the recommendations forced and you would probably see the featured results on your recommendations. Do note though that you should start really small/basic on your view if you are trying to do this forced result approach. In our case, it was kind of hard to use this approach and test what we needed to as we really lean on context for most part. But, probably it might work on basic use cases.

The Real Deal – Coveo Recommendations

In my last post, I focused on the visual clues. If you have not already, please read the first post on coveo recommendations here

In this post, we will focus on actual steps once you did decide that Coveo Recommendations will serve your requirement on hand. Coveo, as always does awesome job with the documentation on how to use recommendations by following the steps noted below. Since Coveo does such a good job at documentation, I am not going to repeat myself here and refer you all to check out this page here

Now to highlight our experience when we followed the steps noted on the Coveo documentation, we learned the below on each step along the way:

Step #1 – Currently, there is no way to actually see the page view events from Coveo Administrative tool, but, you have two check points to quickly note if page views are being captured. Quick screenshots below for reference

Step #2 & Step #3 : It is one of the most straight forward steps and after you quickly add the pipeline and model, you should be able to see them up on Coveo Administrative tool

Go to Models under Machine Learning section

Query Pipelines
You should be able to click on Pipeline, go to machine learning tab and click on edit for the model to see the settings on training set, that is one of the most important settings to ensure you set to appropriate values based on your data set.

Step #4 & Step #5: We figured that this is actually not needed in our case. It was working fine with out doing any additional set up, turns out this was just for sanity or may be older versions of Coveo for Sitecore, not sure. But, was not needed for us.

Step #6 : So, this step once we have our own datasource item, we added Coveo Recommendations to our presentation on all templates that needed to show this component. When we added this component, we could see a new call fire off on XHR requests that would go fetch recommendations. It also started maintaining history of the user views and sent that along with request. We encountered an error here because one scenario where special characters persisted in Title field of the page would cause server error as noted here . We submitted a PR for this scenario and the fix was included in latest release of JS framework

That is it and the last step was publish and we figured we should start seeing recommendations right away. But, it is not that simple. 🙂 In my next post, I will go over the various tricks we did to get the recommendations to show on our pages where we inserted this component.

Additional note here, we did want to show only product recommendations, so, to avoid additional filter additions in our case, we chose to add content type on our page views which we can then utilize on our filter on model to show only specific content type like below.

As you can see the specific filter allows you to pass in a string for content type which is actually set on Sitecore on the rendering properties for Coveo Page Analytics
This should be picked on datasource set on Coveo Page View Analytics rendering

Next up, I will share how we did the filters, forced recommendations, a quick tip shared by @vbernard when everything else fails on how to trick the system to actually send in some recommendations and any other issues we encountered while implementing recommendations using Coveo.

Visual Clue for Coveo Recommendations

Coveo offers a bunch of cool ML functionality. As some of you may already know, growing and providing ML relevance in various streams of website journey is one the main goals of Coveo and where it is heading as an Enterprise product. Coveo has some very good documentation on what their ML components are and how to get started with these here

But, given all that, it is still hard to put a finger on to whether a specific ask or requirement could fit in and benefit with the use of Coveo ML component. So, I decided to blog on our journey beginning from a thought to reality. It was a lot of fun and some additional twists due to lot of context specific filters that were needed to ensure we only show what is truly relevant to the context to top the recommendations that Coveo thinks are apt based on user journey.

So, in this blog I would like to focus on when to know and understand that the current requirement on hand could be a good candidate to implement Coveo solution instead to get the powerhouse technical bits that Coveo is real proud of. Now, it all started when for the very first time I heard a high level requirement around showing recommended products on a e-commerce platform based on user history in combination with couple of Sitecore based fields. My first immediate thoughts and concerns when I hear lot of content management effort would be :

  • Data Integrity – When lot of manual steps are involved, it is usually hard to have a tap on data integrity even with proper workflows in place
  • Tedious and frustrates Content Authors – The more there are to steps, the more it keeps getting on the pile of TODO for the team of CA. Probably the team might never get to it if the priorities change

Now, lets focus for a second on first requirement, so, it is based on user browsing history. If we are confident on the patterns and can learn from how user navigates between products, do we then have a better way of projecting what the user may be interested in rather than making our CA team work hard? Yes, it is an absolute Yes!. Coveo Recommendations component does exactly that by tracking and learning constantly as user explores the site, the model is then capable of returning recommendations.

So, say, there is a scenario where user interactions should not matter and probably the relation ship data between products is coming from a ERP or CRM based system? In this case, since we do not need relevance power of Coveo and is just mostly business logic driving a finite result set, this would be a perfect opposite use case where you could pull it off with few simple SOLR queries to get what you need.

It is very important to get the decision finalized before you dive deep and actually use a cool component Coveo has handy. So, if you are going forward with implementing Coveo Recommendations component, this is a good place to start and understand the steps needed to build one. In my next blog as part of this series, I will explain each one in detail, later will move on to context based filters, hive components to use, sample results to test some HTML with.