How To Create A Search Page In Umbraco

Do you need to implement a site search within your Umbraco website? Then read on. Search is technically one of the pages on a lot of projects. A basic search is pretty easy to get started, but the further down the rabbit hole you get, the more complicated things become. Before I panic you too much, this article is aimed at the majority of you who probably only need a basic site search, that allows people to search and get relevant results. If you need things like faceted filtering, indexing of content from an API, search that integrates with your e-commerce PIM then this article isn't for you, good luck, though!

Getting Started With Search

I've talked previously about Lucene/Examine within Umbraco here. This article is going to follow a very similar path, but the main difference will be the focus towards the MVC parts, more than the Lucene bit. To get started, you'll need to configure two config files to create a new search index. A search index is a collection of files that will live on your web server that will contain details of your web pages. The search will do all the main searching against these files, rather than the Umbraco database. In order to get started, you need to create a new index and define everything that you want to be included in your site search. In your 'Config' folder you should find two files:
<strong>/Config/ExamineIndex.config</strong>
<strong>/Config/ExamineSettings.config</strong>

First, in the ExamineIndex.config we will create a new index, like so:
 <IndexSet SetName="SiteSearch" IndexPath="~/App_Data/ExamineIndexes/SiteSearch/">
  <IndexAttributeFields>
  <add Name="id" />
  <add Name="nodeName"/>
  <add Name="updateDate" />
  <add Name="writerName" />
  <add Name="nodeTypeAlias" />
  </IndexAttributeFields>
  <IndexUserFields>
  <add Name="mainContent" />
  <add Name="nodeTypeAlias" />
  <add Name="mainContent" />
  <add Name="conclusionText" />
  <add Name="contentArea" />
  </IndexUserFields>
  <IncludeNodeTypes>
  <add Name="LandingPage" />
  <add Name="TutorialPage" />
  <add Name="SubCoursePage" />
  <add Name="CoursePage" />
  <add Name="GuidePage" />
  </IncludeNodeTypes>
  </IndexSet>
To create an index, you need to follow the format listed above. In the IncludeNodeTypes add the document types you want to be included in the search. In the IndexUserFields you include the custom fields within your document types you want to be included. In IndexAttributeFields you add the default Umbraco properties you want to be included. The other important thing is the set name. This is a custom name you can call whatever you want. This is the name you will use to reference your index in your code, so it's worth making a note of! Next, we'll need to add an index and search provider in Examine Settings.config, which will look like this:
  <add name="SiteSearcher" type="UmbracoExamine.UmbracoExamineSearcher, UmbracoExamine"
  analyzer="Lucene.Net.Analysis.Standard.StandardAnalyzer, Lucene.Net" indexSet="SiteSearch" enableLeadingWildcards="true"/>
This node needs to be placed within the -> tag. Now we can finally start writing some code!
public class SearchPageController : RenderMvcController
  {
  public ActionResult Index(RenderModel model, string searchTerm)
  {
  var searcher = ExamineManager.Instance.SearchProviderCollection["SiteSearcher"];
  var searchResults = searcher.Search(searchTerm, true).OrderByDescending(x => x.Score).TakeWhile(x => x.Score > 0.05f);

  return CurrentTemplate(data);
  }
  }
Like most of my MVC tutorials, I'm assuming you're using route-hijacking. In terms of architecture, this is the approach you should follow and it is considered bad practice to put logic within your views. In the example above, we use the ExamineManager to select which search provider to use. This is the name you defined above. We then perform the search, passing in a search term into the 'Search' method within the provider and then I use some simple LINQ to ordering the results based on the relevance.
  <ul>
  @foreach (var item in searchResults)
  {
  <article class="search-result">
  
  <div class="col-md-11">
  <a title="@result.Name" href="@result.Url" >
  @result.Name
  </a>
  </article>
  }
As long as everything has been set-up correctly, your query should return results. In your Razor view you can then render that out, the same as you would any other list, as you can see above for example.

submit to reddit

Jon D Jones

Software Architect, Programmer and Technologist Jon Jones is founder and CEO of London-based tech firm Digital Prompt. He has been working in the field for nearly a decade, specializing in new technologies and technical solution research in the web business. A passionate blogger by heart , speaker & consultant from England.. always on the hunt for the next challenge

Back to top