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. 🙂

Implement Coveo on Multi Tenant/Multi Language Architecture

I am very excited to start this series as we are almost close to pulling off Coveo Cloud Implementation on a multi site/multi language Sitecore Instance using legacy Coveo For Sitecore Javascript Framework to support web forms Sitecore Implementation.  I am gathering my thoughts around all the challenges we faced while getting Coveo to work seamlessly with complex Sitecore Instance.  Some were very straight forward and some were anything but that. 🙂

I am going to list down each important problem and note options to tackle each.  Do note that though most of the solutions I would attempt to provide are generic, it highly depends on your Sitecore implementation and customization done to Sitecore in general.

One thing that really helped me solve some of these is understanding when and where Coveo connects with Sitecore.   I would recommend to deep dive on this to any one who is attempting to implement Coveo For Sitecore on their multi tenant and multi lingual Sitecore implementation.

I will start by noting the first problem we faced right after Coveo for sitecore installation on our system.  On Diagnostics page, we had the error such as noted in question and answer below.

https://answers.coveo.com/questions/15435/coveo-search-rest-endpoint-invalid-uri-the-format.html?childToView=15530#comment-15530

One of the first question to answer when implementing Coveo For Sitecore is – Does your Sitecore implementation have a custom link manager as that drives what you would need to watch out for or customize if needed, a quick way to check would be

-> Go to your /sitecore/admin/showconfig.aspx and examine what you see in the node below.  if you see default provider as something other than “sitecore”, then, you can ensure that there has been some customization done on this.  To be honest, any medium to high sized Multi tenant instance that has been active on Sitecore for long time would have some customization around it.  So, it is even more important to know how to ensure Coveo works with your custom link provider settings.

link provider section on config

For instance, in our case languageembedding setting on Linkprovider was set to “always” which means that any website/site served by Sitecore, when a link is generated it would append language to it.  That should surely ring some bells, in  Coveo For Sitecore case upon installation of package, you would see three new sites in the <sites> node when you take a peek at showconfig which are named as coveo_website, coveoanalytics, coveorest.  We definitely do not want to add language embedding on these URL’s here to ensure we do not throw off internal business logic on Coveo end.

To gracefully solve this, I would recommend having an ability to use different Link Providers per site.  There is a very decent solution compiled by my favorite Sitecore MVP Jammy Kam below.

Site Specific Link Provider for Multisite Implementation in Sitecore

By doing this we can assure that Coveo specific sites do not have language embedding in it that would cause issue noted on Q&A above.

Of course, if your sitecore implementation was done more on old school style where the answer was – There is a pipeline for that. 🙂

In those cases, check to see where you can ensure to exclude Coveo sites from having language embedding on them.

One open question I do have is would this be any different with Sitecore 9.0+, a short answer might be a NO.  If any one has any input in regards to this, leave a comment.

That is it about our first ever hiccup, more to come soon.  My hope is that this series will help any one who is driven to use Coveo for Sitecore components and power of framework on a complex Sitecore instance, but, are worried that it might be quite a feat or they might be safe using total custom system.  You can re-visit my blog on this topic and I am sure you will get confidence in sticking to framework instead.  🙂

Tune in for more on this series!

 

 

Experiment with Ease

background experiment

When you are stuck in a problem, do not get scared to experiment!  You might be successful at solving the problem or not, but, every time you let go of your fears and experiment, you end up learning some thing new every single time.

On one of our heavy custom implementation with Coveo due to super complex architecture which uses Web forms, I exactly had to to that.  Funny story,  I am so used to MVC that literally when I dream of a solution I do so, you guessed it right in MVC. 🙂

So, we had a situation where we need to use Coveo Search Box component on shared content which could span across multiple sites and hence the URL should not be based on item and should rather be based on context.  While looking for a solution I bumped in to the below Q&A, but, the solution was for MVC.

https://answers.coveo.com/questions/9939/how-to-configure-coveo-search-box-view-rendering-o.html

I wanted to see how I can implement this on web forms and searched to find a parallel solve for the same with no luck.   So, the only option left was to experiment to see if it will actually work.

To prove my theory, I opened up couple Coveo dll’s to see how I can use Inheritance to swap the Model.  Turns out, it is possible to swap the Model out with few extra steps than MVC.  Do note, that in MVC the model swapping could be done on the View Rendering item to use your custom coveo search box model instead of OOTB coveo model.

So, below are the extra steps for web forms to achieve what is noted for MVC on the Q&A.  We tried these below and it works perfectly alright. 🙂 Rest of the steps should be similar to what is noted on the Q&A noted above, so, I will not repeat the awesome steps that Jean-François L’Heureux provided.

  1. In your duplicated Custom Coveo Search Box sublayout, let us call it CustomCoveoSearchBox.ascx change the inherits to your own custom class
    Inherits=”Coveo.UI.CoveoSearchbox”
    Would become
    Inherits=”ProjectName.Search.Extensions.CustomCoveoSearchbox”
    Use your best judgement or project guidelines to decide a namespace for your custom coveo search box class. 🙂
  2. Next step is to pass in your CustomSearchboxModel (a new custom class that would inherit SearchboxModel) in the OnLoad override of your CustomCoveoSearchBox  class.   Your CustomSearchboxModel would provide your new implementation for GetSearchPageUrl() that would have logic to determine the URL based on site context and other decision factors.

A quick screenshot from Dotpeek of Coveo.UI that helped me with the decisions.

CoveoSearchModel

Hope this helps some one battling the situation on web forms based Sitecore instance.

 

 

Coveo Cloud Learnings – Part 3

Follow my trail if you have not  read coveo cloud part 1 and 2.  Get a read on them here –

Coveo Cloud Learning – Part one 

Coveo Cloud Learning – Part two 

This is the last blog of this series, but, of course there is no end to learning.  I will continue to post new blogs as and when I encounter an interesting thing to share with you all as I proceed to take on new challenges and projects.

On this blog, I will cover how we used underscore, organized our views for better maintainability and all of this with Helix in play.

First though, Coveo does do an awesome job of documenting how to split result templates on conditions which comes in handy in various json situations.  Learn more here:
https://docs.coveo.com/en/413/javascript-search-framework/result-templates

After some pondering, we did go with data-condition route on our result templates.  We also have to remember to have a default result template at the last in the pile.  For better maintainability, we chose to add in partial views in MVC.  We do not have dynamic views as we only have a set of types.  If your implementation calls for content author control over these, you might choose to provide that additional layer of flexibility.  For us, it is an overhead in various ways, so, we avoided that and loaded the partial views on our own custom coveo search view.

Some thing like below:

@Html.Partial(“~/Views/Search/ResultTemplates/ProductResultTemplate.cshtml”, Model)
@Html.Partial(“~/Views/Search/ResultTemplates/StandardResultTemplate.cshtml”, Model)
@Html.Partial(“~/Views/Search/ResultTemplates/GeneralResultTemplate.cshtml”, Model)

Also, we definitely needed some same key attributes on all of this views and we do not want the Controller code to actually hit every single time, it would be in-efficient.  So, we chose to have a custom coveo model that inherits from the Search Model available in Coveo.UI.Mvc.Models with the additional attributes we need.   It was quite easy to make this happen, also, these instructions noted here might come in handy if you are trying something similar.   Awesome post by Vincent. 🙂 Basically, chose bits and pieces I needed to pull this off.

https://source.coveo.com/2014/12/10/creating-custom-model-coveo-for-sitecore/

Now, we have manageable pieces, so, we can work parallel on different result templates and also great for the future when it is time for enhancements.   In real life situations, it becomes very important while working with underscore templates to ensure a specific json piece you are looking for is not undefined and has a value in it, we had quite a few requirements to not even show a matching label on the view if a specific json attribute is missing.  We accomplished that with a simple underscore check as below on those applicable.  Below is a snippet for your reference.

{{ if (!_.isUndefined(raw.yearoforigin) && !_.isEmpty(raw.yearoforigin) ) { }}
<li class=”coveo-product-details__item”>
<span class=”coveo-product-details__category”>@Translate.Text(“Year of Origin”)</span>
<span>{{=raw.yearoforigin}}</span>
<a href=”#” class=”more”>(+)</a>
</li>
{{ } }}

Also, note that we continue to follow Sitecore best practices on the side to load all labels from Dictionary instead of hard coding on the view.  Another thing to note, is for the data conditions you need on the result templates, if it is a static value such as a GUID or string, always follow Helix best practice of having these defined in Templates.cs file of your project.  In our case, we maintained this in Feature Search project.  So, the data condition and templates.cs would look like –

<script id=’faqResultTemplate’ class=’result-template’ type=’text/underscore’ data-condition=’raw.contenttype==”@Templates.ContentTypes.FAQType”‘>

public struct ContentTypes
{
public static readonly string FAQType = “FAQs”;
}

I know, I wish this is not a string and is a GUID, but, unfortunately due to content structure we had to work with has these distributed out in content areas rather than defined templates, so, had to go this route.  But, where you can always rely on GUIDS as that is more stable implementation.

Also, we had lot of external fields which need to be used as Facets in our case.  There is documentation on how to make an external field Facetable, but, one thing to remember is actually a combination that you will need to do to make this work.  You have to do what is noted here and also ensure you add the field to external fields section as well.  As always,  it is always recommended to patch using a special config file on your Helix project rather than updating either custom coveo config  or raw coveo config file.

Say, if I had a field on my Cloud Index called contenttype, I would then add the following on this patch config file to ensure it is facetable and hash is excluded considering this is an external index.

<configuration xmlns:patch=”http://www.sitecore.net/xmlconfig/”>
<sitecore>
<coveo>
<defaultIndexConfiguration>
<fieldMap>
<fieldNames hint=”raw:AddFieldByFieldName”>fieldType fieldName=”contenttype” isExternal=”true” settingType=”Coveo.Framework.Configuration.FieldConfiguration, Coveo.Framework” />
</fieldNames>
</fieldMap>
<fieldMap>
<externalFields hint=”raw:AddExternalField”>
<field fieldName=”contenttype” />
</fieldMap>
</defaultIndexConfiguration>
</coveo>
</sitecore>
</configuration>

Also see this interesting post below that we used to migrate all our external fields on to production sandbox when we are ready.  We had lot of custom fields added to sandbox due to what we were trying to accomplish and wanted to eliminate manual work to load these up and replicate to avoid error and mundane task.  Thanks to coveo team for letting us know a better way does exist.  Take a peek of that here

Another interesting thing I bumped in to while working on this project was how some functionality is abstracted out from us on Cloud as compared to on-premise.  On Cloud, especially when working with trail sandboxes, if you queue way too many rebuilds, it might take a while, so, do not panic and give it some time.  All should be fine unless there is something else going on, if your logs are clean and no obvious errors on cloud console logs, you should be fine and it is just a delay on the cloud queue as trial sandboxes might not be given immediate preference.  If in doubt, talk to your Coveo point of contact and they will calm you down. 🙂

Also, when you are in active indexing state, say items are being added to your external index on cloud.  Sometimes, same queries and parameters passed from your Coveo Search Page/Components could yield different results due to elastic nature of Coveo.  Obviously, this should not happen when indexing is done.  But, I was super curious to know the reason behind this as I was doing some smoke test on my end.

That is all for now you all, have fun and enjoy the week ahead. Happy Monday!

Leave me a comment if you are curious to know more.

 

 

 

 

 

 

Coveo Cloud Learnings – Part 2

search

Last week, I kick started a planned series in effort to pour over my side of story using Coveo Cloud platform first hand.  You can read more on the initial piece here

I am hoping this series will help any one starting a Coveo cloud implementation in making appropriate choices along the way based on project and requirements on hand.  I would also post catches/gotchas that I experienced along this journey as well.

Now,  let us move on to more.  After the initial steps, there are more choices to make such as below.  I wish I could say – go with your  gut, lol.  Always go by a thoughtful and knowledgeable call on each of these.  When in question, use rock solid support from Coveo and Sitecore team.   You can ping on slack channel or load a Q&A here .  More than likely, if your decision is a basic one, there could be one already out there. 🙂

Ensure to squeeze out as much as you can from the OOTB product, Coveo Cloud offers Machine learning and AI that could help users find relevant results.  So, embrace it and try to make it work to your architecture and timing.   In our case, we thought query suggestions are very important.  But, what to do when there is not enough data available on Coveo Analytics that would get back ML query suggestions.  Ensure you always have a back up plan!  We turned on result suggestions with Omnibox component as a back up.  Although, be very careful and diligent to drop this off as these queries are accounted towards the quota you signed up for with Coveo.

A parallel note on ML/Query Suggestions and reminder to ensure to change the tuning parameters on your test sandbox to test your ML query suggestions.  If you leave them to default, it might or not bring up query suggestions.   If you do not know where to find them, go to your Coveo Administration console either via sitecore or direct link if you have one on you, then, click on Query Pipelines under Search section, pick a model you want to tune the settings on and you will see the screen below

trainingset

I also was curious to see and test the ML query suggestions, so, I followed the instructions noted here and could quickly create a new report of my own way to track if there are any ML query suggestions available on my model.

https://onlinehelp.coveo.com/en/cloud/reviewing_suggested_queries_by_coveo_machine_learning.htm

Our Architecture was subtly different as it uses older/legacy Sitecore version to push all the data on to Cloud index using Push API.  We had to ensure we are following all the good practices as much as we can to ensure Coveo can then perform and do it’s thing on relevancy.  Here is a good Q&A link and responses I got when I was eyeing and planning to ensure we are covered with this Architectural decisions we have in play.
https://answers.coveo.com/questions/14602/best-practices-when-using-push-api.html

Another little POC that I had to do on my side to ensure our Architecture decisions will not have any unknown risk on main requirements. One such requirement was to have Coveo Stand Alone search box to be available and working on older version of Sitecore site and it would then redirect to the new version of Sitecore search page that was built off of Coveo components and JS framework.  Initially, I had hiccups due to CORS issue as the domain was not matching, but, later all was cool when we had set up load balancer to swap between old and new sitecore versions.   Below is Q&A reference for this step as well, if you are curious
https://answers.coveo.com/questions/14985/can-we-have-a-coveo-component-html-on-a-site-while.html

Next up, I will add my notes around how we built the components and used underscore and any other caveats we encountered during the same.

That is all for now folks, if you need more information on this subtly different architecture we have in play, feel free to drop in a comment.   Have a great weekend! You all deserve it. 🙂

Coveo Cloud Learnings – Part 1

Coveo_Cloud

I am super excited to share my experiences with you as I rolled up my sleeve to play with super cool search tool out there, Coveo Cloud!

Before I got this chance to work intimately with this platform, I did hear a lot and read a lot.  Was wondering and anticipating, when will I get to actually do hands on and I really wished to do that before I head out to Coveo Impact at SanFrancisco this year. Between, crazy excited to hear all the awesome new things and also geared up to participate in their Hackathon event as well.  Know more about their event here below

http://impact.coveo.com/

Now, I plan to write up my experiences with Coveo cloud first hand, the project is near completion on my end and I think this is the perfect time to reflect on all the set of challenges we had while pulling off a simple yet complex due to Architecture decisions involved on the project.

First things first, when you are about to start implementation on Coveo for Sitecore platform, decide on your version and framework you plan to use.  This goes long way to ensure you picked the correct version that supports all your other related third party components and ensure it is indeed a right step towards desired search experience.

On this project, we chose December 2017 version matching the Sitecore version we are using on this instance.  My first comment on getting Coveo for Sitecore up and running on my local and other environments is “Piece of Cake”.  Compared to challenges, hiccups I and my fellow team members had with on premise version of Coveo, this was a total opposite.  It took me less than an hour as opposed two full days(give or take) with on-premise version.  It was an awesome feeling to see the green quite quickly this time.

While you are at this step in your project, also, decide which version of JS framework would you like to use.  I would vote for Hive as it is new, more robust and modular, but, it highly depends on project of course.   You can see compatibility and more decision factors here on their documentation.

https://developers.coveo.com/display/public/SitecoreV4/What%27s+New+In+Coveo+for+Sitecore+4

While I was doing the steps or while trying to understand the new platform, I tried comparing and contrasting to the knowledge I had working with their on-premise version.  It did help me a lot actually trying to figure – “How is this different from before?”

Some helpful notes on Installation and Set up with Cloud.   Do note that your sitecore indexes, both, master and web would be now on Cloud and so are your logs, content browser and other cool things you were used to pulling up from port 8081, it should now all be located on Coveo Cloud Console. Also, understand that some features are now abstracted out, like you can not turn off and on the live monitoring on indexes for instance.  One important thing to realize is all your index rebuilds are queued in some fashion which you may not have control over, so, talk to your Coveo consultant or drop in a support ticket if you encounter some delays more than usual on your rebuilds.

On our end, we always ensure to use cloud sandbox(trial) for all our lower environments.  Note that there could be some limit on number of indexes on Sandbox, so, check with your Coveo rep when in question.

One subtle catch I would like to mention is – after installation of Coveo for Sitecore and hooking up proper Coveo Sandbox configuration and a full site publish, I did see the web index on the cloud from Sitecore perspective, but, note that master did need a manual rebuild by going in to your Indexing Manager on Sitecore Control Panel.

If you got time on you, explore the Coveo Cloud Administration Console, it has different and clearly named sections that should give you fair idea on which is what, but, it is definitely worth going over this as you drill deep in to Cloud Implementation.

Also, note that with Cloud you can build sample search pages on the fly, it is a cool feature to test some of the fields you have on your index or could be a custom build external index that you would like to target, but, if your implementation calls for some thing more complex, I would recommend to house your search pages within your sitecore instance by customizing the components and adding them to your presentation plus creating the templates.

So, you installed Coveo For Sitecore cloud version, got all green in diagnostics, sitecore indexes in check and could see your items and indexed data on cloud console content browser.  Did I hear that right? That is it, we can now jump right ahead and do some cool stuff that is made possible by the platform.

My next blog will focus on more challenges, gotchas and learning we had during this wave of time.   Also, will expound on choices we made at each step as well.

References/Helpful Resources for Coveo For Sitecore Cloud 

Installation guide:
https://developers.coveo.com/display/public/SitecoreV4/Installing+Coveo+for+Sitecore

Architecture and Beyond
https://developers.coveo.com/display/public/SitecoreV4/Understanding+the+Architecture+of+Coveo+for+Sitecore

Framework Choice

https://developers.coveo.com/display/public/SitecoreV4/What%27s+New+In+Coveo+for+Sitecore+4

Coveo Impact

http://impact.coveo.com/

Versions

https://developers.coveo.com/display/public/SitecoreV4/Downloads