Saturday, August 28, 2010

Using Coveo with Sitecore. Part 2: Performing a Query


This post is a part of the "Using Coveo with Sitecore" series.












There are many ways to retrieve data from Coveo, I'll describe most popular of them, their proc and cons.

Integrating search interface "as is"
Such integration of Coveo can be implemented in a day or even less, including configuring Sitecore Connector which will crawl only changed / newly created items, adding and configuring front-end search.

In order to add search interface to your website you need to:


1. Copy Coveo.CES.Web.Search.dll and Coveo.CNL.Web.dll files from Coveo directory to your website's /bin folder.

2. Setup a virtual directory called /Coveo and point it to this folder: C:\Program Files\Coveo Enterprise Search 6\Web\Coveo

3. Configure Coveo instance you want to use by adding the following lines at the bottom of your web.config file:
<coveoEnterpriseSearch>
    <server hostname="localhost" impersonate="false" mirrorName="default" port="52800"/>
  </coveoEnterpriseSearch>

4. Add references and Coveo search control to the page:
<%@ Register TagPrefix="cnlm" Namespace="Coveo.CNL.Web.Misc" Assembly="Coveo.CNL.Web, Version=6.0.0.0, Culture=neutral, PublicKeyToken=44110d16825221f2" %>
<%@ Register TagPrefix="ces" Namespace="Coveo.CES.Web.Search.Controls" Assembly="Coveo.CES.Web.Search, Version=6.0.0.0, Culture=neutral, PublicKeyToken=44110d16825221f2" %>
<%@ Import Namespace="Coveo.CES.Web.Search" %>
<%@ Import Namespace="Coveo.CNL.Web" %>

<ces:searchinterface id="SearchPanel" runat="server"/>

5. Enjoy the result:



Building your own application based on Coveo controls
Coveo provides a lot of controls that can be quickly reused in your own project. Whole Search Interface is built from .ascx controls that can be found here: /Coveo/Skins/. It makes sense to define custom skin for your project, or even a set of skins and change your website section appearance from Coveo administration tool.
This approach is fast and seems to be easy, but you should not forget that it will not be as customizable as your own code. Also, default controls rely on their own Ajax scripts (pretty large, about 100kb gzipped) and someday you might want to get rid of them.

Using Coveo as a "Data Engine", using your own controls to display the data
Let's talk about the most interesting part - performing queries programmatically.
Coveo query can be defined using SearchBuilder class, most of the queries return results as array of ICESResult[]. The following example will show how to perform a simple query:

public static ICESResult[] GetResults(string field, string value, int maxCount)
      {
         SearchBuilder builder = CreateSearchBuilder();

         builder.AddAdvancedExpression("@{0}==\"{1}\"".FormatWith(field, value));
         QueryWrapper query = QueryWrapperFactory.GetNewQueryWrapper(builder);
         return query.GetResults(0, maxCount);
      }

First we create a query builder and define that we want to find items where field "field" equals "value". Then we perform our query by calling "GetResults" method and passing start index and the number of results..

But what about CreateSearchBuilder method? It's implementation may vary depending on using Coveo controls. If you have any Coveo control at your page, you can get query builder using the following code:

private static SearchBuilder CreateSearchBuilder()
      {
         SearchBuilder builder = new SearchBuilder();
         builder.Provider = SearchBinding.MainSearchObject.Provider;                          
         return builder;
      }

and if you do not use them, it should transform into:

private static SearchBuilder CreateSearchBuilder()
    {
      var builder = new SearchBuilder();
      ICESSearchProvider provider = SearchUtilities.CreateDefaultSearchProvider();
      builder.Provider = provider;
      return builder;
    }

Search Builder initialization is the right place to add any constant expressions that should apply to all queries. For example, if you want to search in the "SitecoreSnippets" index only, you should add the following code:

...
      builder.AddConstantExpression("@Source=SitecoreSnippets");
      return builder;
      ...

Above examples are really simple, if you're ready to go forward - read this blog post: Tag Cloud from Sitecore content., it uses some techniques that will be explained in the next blog post of this series.
Also, you can find interesting demo videos on this YouTube channel and watch the slideshow below(it explains Sitecore metadata indexing in just 11 slides). Thanks to Wim Nijmeijer for sharing these resources.
Coveo - Sitecore

And one more thing - do not hesitate to add your comments if this post misses some details or you have any questions that can be related to the next blog post. Thanks in advance.