USING EXAMINE TO SEARCH CONTENT

As of Umbraco 4.5, Examine, which is a custom search engine built on Lucene.NET, comes standard as part of the backoffice search feature. Because of that, setting up indexers that you can use to search the content that is published on your website is relatively easy.

To setup Examine for your website, follow these simple steps.

  1. Configure a new index set in <install root>/config/ExamineIndex.config. To make this task easy, copy the InternalIndexSet that is already defined. For your reference, this is the one that is used to support the Umbraco backoffice searching. To set Examine up in your Runway site, copy the code in Listing 9-5.
  2. Create a searcher that you can attach to in your .NET code. This searcher specifies a number of settings, such as whether indexing should be handled asynchronously, the binaries to run the search, and which index set should be used when executing a search. All these settings appear in the <install root>/config/ExamineSettings.config. See Listing 9-6 for an example of a searcher for your Runway site. Add the bolded code in Listing 9-6 to your ExamineSettings.config file.
  3. Gain access to the indexes that are created when you publish a node. You do this by creating a .NET macro with the contents in Listings 9-7 and 9-8. For information on creating macros, see Chapter 5.
  4. Add the Search Results macro to a page or template so that you can call the URL in a browser. For example, add it to http://umbracousersguide.local/search-results.aspx.
  5. Add a search field to your master template that simply redirects to your newly created search macro and appends the search term in the URL query string s. Listing 9-9 shows an example of this. Copy the code in Listing 9-9 into your Runway.Master template.
  6. Restart the application. You do this by simply resaving the web.config file in the <install root>web.config.

LISTING 9-5: ExamineIndex-partial.config

image
<IndexSet SetName=“RunwayIndexSet”
   IndexPath=“∼/App_Data/ExamineIndexes/Runway/”>
      <!-- fields specific to Umbraco -->
    <IndexAttributeFields>
      <add Name=“id” /> <!-- required -->
      <add Name=“nodeName” /> <!-- required -->
      <add Name=“updateDate” />
      <add Name=“writerName” />
      <add Name=“path” />
      <add Name=“nodeTypeAlias” /> <!-- required -->
    </IndexAttributeFields>
      <!-- fields that you have defined in your various document types -->
    <IndexUserFields>
      <add Name=“bodyText” />
      <add Name=“sidebarContent” />
    </IndexUserFields>
    <IncludeNodeTypes />
      <!-- specify any document types that you do NOT want to be indexed -->
    <ExcludeNodeTypes>
      <add Name=“FAQArea” />
    </ExcludeNodeTypes>
</IndexSet>

image The IndexPath that you specify must be writable by IIS. If IIS does not have write privileges on this folder, the index won't be created and therefore cannot be searched.

LISTING 9-6: ExamineSettings-partial.config

image
<Examine>
  <ExamineIndexProviders>
    <providers>
        …
        <add name=“RunwayIndexer”
type=“UmbracoExamine.MemberLuceneExamineIndexer, UmbracoExamine”
             runAsync=“true”
             supportUnpublished=“true”
             supportProtected=“true”
             interval=“10”
             analyzer=“Lucene.Net.Analysis.Standard.StandardAnalyzer,
Lucene.Net”/>
        …
    </providers>
  </ExamineIndexProviders>
  <ExamineSearchProviders defaultProvider=“InternalSearcher”>
    <providers>
        …
        <add name=“RunwaySearcher”
          type=“UmbracoExamine.LuceneExamineSearcher, UmbracoExamine”
            analyzer=“Lucene.Net.Analysis.Standard.StandardAnalyzer,
Lucene.Net”
            indexSet=“RunwayIndexSet”/>
        …
    </providers>
  </ExamineSearchProviders>
</Examine>

LISTING 9-7: SearchResults.ascx

image
<%@ Control Language=“C#” AutoEventWireup=“true” CodeBehind=“SearchResults.ascx.cs”
Inherits=“UmbracoUsersGuide.usercontrols.SearchResults” %>
<%@ Import Namespace=“UmbracoUsersGuide.usercontrols” %>

<%-- provide some stats of the search here --%>
<p>
    Your search for :&nbsp;<b><u><%=SearchTerm%></u></b>&nbsp;returned&nbsp;
    <i><b><%=this.SearchResultsCollection.Count()%></b>&nbsp; result(s)</i>
</p>

<%-- Create a simple repeater template to use for output --%>
<asp:Repeater ID=“SearchResultListing” runat=“server” >
    <HeaderTemplate>
        <ul class=“search-results”>
    </HeaderTemplate>
    <ItemTemplate>
        <li>
            <a class=“title”
href=“<%#((Examine.SearchResult)Container.DataItem).FullUrl()%>”>
                <%#

((Examine.SearchResult)Container.DataItem).Fields[“nodeName”]%>
            </a>
            <div class=“details”>
              <p>
    <%#((Examine.SearchResult)Container.DataItem).GetDetails(300)%></p>
            </div>
            <div class=“url”>
                <a
href=“<%#((Examine.SearchResult)Container.DataItem).FullUrl()%>”><%#((Examine.
SearchResult)Container.DataItem).FullUrl()%></a>
            </div>
        </li>
    </ItemTemplate>
    <FooterTemplate>
        </ul>
    </FooterTemplate>
</asp:Repeater>

LISTING 9-8: SearchResults.ascx.cs

image
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Examine;
using UmbracoExamine;
using UmbracoExamine.SearchCriteria;

namespace UmbracoUsersGuide.usercontrols
{
    public static class SearchResultExtensions
    {
        // Create a set of helper methods to make output
        // cleaner.
        public static string FullUrl(this SearchResult sr)
        {
            // Generate the URL for the returned node using
            // the umbraco library method NiceUrl.
            var urlStr = umbraco.library.NiceUrl(sr.Id);
            return urlStr;
        }

        public static string GetDetails (this SearchResult sr, int length)
        {
            var contentStr = “”;
            var truncateStr = “…”;
            if (sr.Fields.ContainsKey(“bodyText”))
            {
                contentStr = sr.Fields[“bodyText”];
            }
            else if (sr.Fields.ContainsKey(“question”))

            {
                contentStr = sr.Fields[“question”];
            }
            else if (sr.Fields.ContainsKey(“answer”))
            {
                contentStr = sr.Fields[“answer”];
            }

            // Only show the first 300 characters of the node
            // contents and use that as the preview of the
            // page content in the repeater.
            if (contentStr.Length > length)
              contentStr=contentStr.Substring(0, length) + truncateStr;
            return contentStr;
        }
    }
    public partial class SearchResults : System.Web.UI.UserControl
    {
        /// <summary>
        /// The term being searched on
        /// </summary>
        protected string SearchTerm { get; private set; }

        /// <summary>
        /// The search results list
        /// </summary>
        protected IEnumerable<SearchResult> SearchResultsCollection
                { get; private set; }

        public SearchResults()
        {
            // Initialize the class with some default values
            SearchTerm = string.Empty;
            SearchResultsCollection = new List<SearchResult>();
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            // Grab the search term from the URL query string
            // ‘s’, if it's null or empty break out of this load
            // event.
            SearchTerm = Request.QueryString[“s”];
            if (string.IsNullOrEmpty(SearchTerm)) return;

            // Setup the search criteria by pointing to the searcher
            // that you created in ExamineSettings.config
            var criteria = ExamineManager.Instance
                    .SearchProviderCollection[“RunwaySearcher”]
                    .CreateSearchCriteria(IndexTypes.Content);

            // Configure a filter that will query all of the fields
            // that you have specified below and that you can feed to

            // searcher below.
            var filter = criteria
               .GroupedOr(new string[] { “nodeName”, “bodyText”, “question”,
                   “answer” }, SearchTerm)
               .Not()
               .Field(“umbracoNaviHide”, “1”) // filter out the hidden pages
               .Compile();

            // Execute the actual search, again pointing to
            // the searcher that was configured in
            // ExamineSettings.config.
            SearchResultsCollection =
             ExamineManager.Instance
               .SearchProviderCollection[“RunwaySearcher”]
               .Search(filter);

            // Bind the results to the repeater that's in the view
            SearchResultListing.DataSource = SearchResultsCollection;
            SearchResultListing.DataBind();
        }
    }
}

LISTING 9-9: SearchFieldForTemplate.txt

image
<input type=“text” id=“search-term” name=“search” value=“” />
<input type=“button” name=“searchBtn” value=“Search” onclick=“runSearch();” />
<script type=“text⁄ javascript”>
    function runSearch(){
         var searchResultsUrl =
        “http://umbracousersguide.local/search-results.aspx”;
        document.location.href = searchResultsUrl + “?s=” +
           document.getElementById(“search-term”).value;
    }
</script>
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset