More in this section

Forums / General Discussions / Google Custom Search to replace built-in search

Google Custom Search to replace built-in search

1 posts, 1 answered
  1. Tony
    Tony avatar
    20 posts
    12 Oct 2012
    12 Oct 2012
    Link to this post
    So we've had issues with indexing and various other problems with the built-in Sitefinity search.  We were looking around for other solutions and decided to go with a Google Custom Search and disable the built-in.  When we migrated over to Sitefinity March of this year we had some 7000 pages so I'm not sure where we're at now.. They're almost all what the built-in search considers Static HTML so this could be why we're having trouble indexing them.  I've mostly finished implementation and wanted to share my experience. I'm definitely not the greatest developer and I might have done a few things inefficiently or incorrectly so I'm more than open to any feedback.  It's important to note that we're having to pay beyond the free portion of this, so I would check and make sure it's the best solution for you before you implement it on production.  I believe without a credit card on file with your API account Google limits you to 100 queries per day.  We just thought this would be a cheaper solution than buying our own Google appliance and more fiscally efficient than paying for their SiteSearch service.  Also you're limited to a maximum of 100 results... We decided this wasn't that much of a limitation compared to what we were currently working with.

    Here is an example of results from the built-in Sitefinity search on our page..

    As you can see there are only 5 results.. Other organizations may not have an issue with the built-in but you can see from the two queries I'm about to show you that we're having major issues.  This index was created September 14th by the way so it's had plenty of time to crawl our site.  We've had so many issues with indexes that we've blown away the original one from March for troubleshooting purposes.. could be why it's so much smaller than it should be because from what I understand it indexes while you publish a page and it crawls content.  Actually the indexing while it publishes a page is what killed us back before SF5... Something to do with our BigIP load balancing environment it would cause major issues with constant timeouts during publishing and server performance degradation.  

    Here is an example of the same query using Google Custom Search Engine:

    The test query returns the maximum of 100 results.. That's a pretty huge difference.  Another thing I like about using this is that I can pass in a different domain than our so I can use it to query our external eHealth library we get through Staywell to make for a significantly more user friendly search experience, I just haven't finished doing it yet :-)

    To start off with I decided to do this all server side with the Google .NET API (in my \bin folder).  I wrote a simple class that I could use to interact with it so I could expand it out to a web service with JavaScript calls later on to improve my search results control.  For now to get started though my control is just an objectdatasource and a listview that binds to it.  So far I only have two methods getResults() and getTotalResults().  I'm not really great with caching in the session state so please please tell me if I'm doing things weird here.

    I did most of this a couple of months ago and didn't get back to it until yesterday.. These are copies from my dev box that I've removed most of our specific data like proxies to get past firewalls and such.. I'm only saying this because there could be something new on here that I haven't published that breaks certain functionality.. I don't think that's the case but it's possible.

    Here is my GoogleCSE class  I have it sitting out in my \App_Code directory.

    Here is the ascx for my user control.. Like I said I plan on handling this more manually and cleaner later on, but for now I'm just using an objectdatasource for my GoogleCSE class.  

    01.<%@ Control Language="C#" AutoEventWireup="true" CodeFile="search.ascx.cs" Inherits="Custom_Widgets_Templates_search" %>
    03.       <asp:ObjectDataSource ID="googleCSEDataSource" runat="server"
    04.            SelectMethod="getResults" TypeName="GoogleCSE"
    06.             SelectCountMethod="getTotalResults"
    07.            MaximumRowsParameterName="maxRows"
    08.            StartRowIndexParameterName="page"
    09.            EnablePaging="True">
    10.            <SelectParameters>
    11.                <asp:QueryStringParameter Name="query" QueryStringField="q" Type="String"
    12.                    DefaultValue="" />
    13.                <asp:QueryStringParameter DefaultValue=""
    14.                    Name="siteSearch" QueryStringField="u" Type="String" />
    15.                <asp:Parameter DefaultValue="10" Name="maxRows"
    16.                    Type="Int32" />
    17.                <asp:QueryStringParameter DefaultValue="1" Name="page" QueryStringField="p"
    18.                    Type="Int32" />
    20.            </SelectParameters>
    21.        </asp:ObjectDataSource>
    23.        <asp:ListView ID="ListView1" runat="server" DataSourceID="googleCSEDataSource" ViewStateMode="Disabled">
    24.                <LayoutTemplate>
    25.                    <div class="gseResults">
    26.                        <asp:PlaceHolder ID="itemPlaceholder" runat="server" />
    27.                    </div>
    28.                    <asp:DataPager ID="DataPager1"  PagedControlID="ListView1" runat="server">
    29.                        <Fields>
    30.                          <asp:NextPreviousPagerField FirstPageText="<<" ShowFirstPageButton="False"
    31.                                 ShowNextPageButton="False" ShowPreviousPageButton="False" />
    32.                          <asp:NumericPagerField ButtonCount="10" />
    33.                          <asp:NextPreviousPagerField LastPageText=">>" ShowLastPageButton="False"
    34.                                 ShowNextPageButton="False" ShowPreviousPageButton="False" />
    35.                       </Fields>
    36.                    </asp:DataPager>
    38.                </LayoutTemplate>
    39.                <ItemTemplate>
    40.                    <a href="<%# Eval("Link") %>"><span class="gseTitle"><%# Eval("HtmlTitle") %></span></a>
    41.                    <div class="gseResult">
    42.                        <div class="gseURL">
    43.                            <%# Eval("HtmlFormattedUrl")%>
    44.                        </div>
    45.                        <span class="gseSnippet">
    46.                            <%# Eval("HtmlSnippet")%>
    47.                        </span>
    48.                    </div>
    49.                </ItemTemplate>
    50.        </asp:ListView>
    51.        </div>

    The code behind isn't doing anything..
    01.using System;
    02.using System.Collections.Generic;
    03.using System.Linq;
    04.using System.Web;
    05.using System.Web.UI;
    06.using System.Web.UI.WebControls;
    08.public partial class Custom_Widgets_Templates_search : System.Web.UI.UserControl
    10.    protected void Page_Load(object sender, EventArgs e)
    11.    {
    13.    }

1 posts, 1 answered