Building a navigation system for a news or blog based on years and months (like an archive as an example) requires that we know what years and months are available for:
- The top level – as in when we open the home page
- Expanded – whenever we are viewing a month or article page and need to expand accordingly
- Dynamically – when we need to build the navigation in one shot, perhaps as an accordion or similar.
Note – we are assuming the following structure:
Its possible to code around these by doing Axes calls on the current item and getting the parents and siblings but this doesn’t scale well. Especially if you need to start dropping into sibling months to hide and show depending if they’re empty or not. And we haven’t even talked about languages.
An alternative approach is to use your Lucene index and scan it for all your news items in the current language and group them by year and month and store counts for each. Then you can cache this for even more speed.
Ok, so – Cardinal Rules Queries has recently had a beta release, you can find it here. It allows you to leverage the power of the rules engine in Sitecore to build queries based on Lucene.Net, and if you choose – other search tools. Please see my initial post Sitecore Rules Queries Pt I for a bit more information.
Following on from this, I thought I would write a quick article on how you actually use it in code. Please note this is subject to change, but is correct at the time of posting.
In this post I will be looking at how to drive a lucene search by using the Sitecore Rules engine.
Pretty much since I started using Sitecore, I have found that Lucene has been the get out of jail when it comes to performance. In fact, I can’t remember the last time I used Sitecore queries or the item axes. As a developer I have always been happy to write such methods as GetDescendants(ID itemId, ID templateId).
What about giving this power to the user though?
The rules engine in its default form is a great tool but executing a rule against a bunch of items becomes a iterative process and often can carry a performance penalty. This got me thinking – could I use the rules engine to drive the Sitecore Search Layer?
In this post I will be looking at using Lucinq to drive search using the default sitecore 7 indexing.
Lucinq provides the ability to use the generic forms of the standard Term, Phrase, Wildcard and other methods. This allows the assignment of an expression to denote which of the fields is the target of the query.
In the line below, you can see an example of this in action
queryBuilder.Term(t => t.Content, "value")
This tells Lucinq to read the IndexField attribute from the Content field of the SearchResultItem class and use that as the field for the Lucene query that is to be sent down.
* Note, the .HasBaseTemplate() method of Lucinq’s query extensions requires a change to the default Sitecore indexing settings. *
Here is an example in situe – this can be can in unit tests WITHOUT the need to run the sitecore initialise pipeline (unlike SC 7 search).
// the index lives in the appdata folder, so using a Server.MapPath to get the real path for Lucene.
string searchIndexPath = Server.MapPath(Settings.IndexFolder + @"/lucinqwebindex");
using (SitecoreSearch search = new SitecoreSearch(searchIndexPath))
ISitecoreQueryBuilder queryBuilder = new SitecoreQueryBuilder(SitecoreMode.Sitecore7);
queryBuilder.TemplateId(ContentIds.HomeTemplateId); // add template id to the query
// below users the sitecore index field attribute, its the same as
// queryBuilder.Term("content", "value");
queryBuilder.Term(t => t.Content, "value");// set up the term based on the in built sitecore 7 class.
ISitecoreSearchResult searchResult = search.Execute(qb);
int totalResults = searchResult.TotalHits; // gets the total number of results
List items = searchResult.GetPagedItems(1, 10);
More information can be found on Lucinq on github here
In this post I will cover using Lucinq with sitecore – in particular returning the results through the Glass Sitecore Mapper.
Returning results from lucene is something we as Sitecore developers have been used to for some time. Lucene provides hyper fast searching and its flexible storage makes it great for indexing content. However, in use, the API is somewhat verbose and not necessarily the easiest to understand without reading up on it first (I still would recommend the book Lucene In Action to get a grounding in the product).
I have a few issues with the search layers that Sitecore have implemented over the years which I won’t go into in this post.