Step 2: Implement a Query Runner Class
Searcher contains a list of all query methods available to interrogate the search indexes. Query Runner contains the processing logic for each query.
For every method run in Searcher.cs, Query Runner is called behind the scenes. To see how each query is constructed look in QueryRunner.cs. This is also where each query is run.
QueryRunner.cs
To create a query runner:
1. First add the following namespaces:
namespace Sitecore.Training.Index { #region Usings using System; using System.Collections.Generic; using System.Linq; using Lucene.Net.Search; using Lucene.Net.Index; using Lucene.Net.QueryParsers; using Lucene.Net.Analysis.Standard; using Search; using Diagnostics; using Data; using Collections;
2. Name the class Query Runner
public class QueryRunner : IDisposable
3. Create the following constructor:
public QueryRunner(string indexId) { Index = SearchManager.GetIndex(indexId); }
This constructor gets the appropriate search index. It calls the SearchManager class with the GetIndex method and uses index as a parameter. The IndexId parameter can refer to either the training master or training web indexes.
4. Create a property called index:
public Index Index { get; set; }
5. Create two query runner methods. Both of these use the same parameter called query but the type is different.
QueryBase = Sitecore.Search
Query = Lucene.Net
| Query Method | Description |
| SearchResultCollection RunQuery(QueryBase query) | Using Sitecore.Search API – this method expects Sitecore queries |
| SearchResultCollection RunQuery(Query query) | Using Lucene.Net API – this method expects Lucene queries |
5. Create your search methods (queries). These are the same as the methods listed in Searcher.cs. The table below describes each of these methods in more detail. View the Visual Studio solution to see the full source code for each method.
| Method | Description |
| GetItemsByFullTextQuery(string query) | Searches through all the text contained in the item fields, including Rich Text fields and meta-data. |
| GetRelatedItemsByMultipleFields(string query, SafeDictionary<string> refinements) | Called from the SearchManager.Search() method via Searcher.GetRelatedItemsByMultipleFields: Get the refinements from the query string: var refinements = WebUtil.ParseQueryString(WebUtil.GetQueryString());
refinements.Remove(“search”); Pass them on to the searcher: var results = searcher.GetRelatedItemsByMultipleFields(searchString, refinements); This method links to a list of dictionary refinements and adds category and brand as refinements to the search. |
| GetRelatedItems(string ids) | Gets all relations without specifying a field. Get related items by list of Ids and returns a pipe separated list of ids. |
| GetRelatedItemsByField(string ids,string fieldName, bool partial) | Extends the GetRelatedItems method by adding more parameters. This method can be used effectively to return items in bidirectional relationships. |
| ContainsItemsByFields(string ids, string fieldName, string fieldValue) | For refinements to work – to check if a category relates to any of the items returned in the search results. |
6. Define the following Clause Construction Helper classes:
AddFieldValueClause(BooleanQuery query, string fieldName, string fieldValue, BooleanClause.Occur occurance)
AddPartialFieldValueClause(BooleanQuery query, string fieldName, string fieldValue)
AddFullTextClause(BooleanQuery query, string searchText)
ApplyIdFilter(BooleanQuery query, string fieldName, string filter)
ApplyRelationFilter(BooleanQuery query, string ids)
The Helper classes perform some extra validation on GUIDs before allowing them to be used by the search indexes. All GUIDs are first converted to lowercase and then given short IDs. Lucene also checks for and filters out any stop words. It is necessary to normalize GUIDs in this way to avoid unexpected results when querying.
7. Return a search index specified by ID.
public static Sitecore.Search.Index GetIndex(string indexId) { return SearchManager.GetIndex(indexId); }