Sitecore 7: Ensuring IQueryable ordering with string fields

Sitecore 122I hadn’t had the chance to really play around with the indexing options in Sitecore 7 until this past week when I needed to build a listing page from an index and sort it by the page title. At first, I just couldn’t get it to work. The ordering never seemed to match up to the actual title field I was ordering by. Time to dig into the indexing configurations!

How it happens

In order to ensure the collection is returned in the same order every time, you need to do the ordering on the IQueryable instance before retrieving the Item data for the segment you need.  This is particularly important when you are implementing paging and using Skips and Takes to grab a page’s worth of content at a time. In order to apply ordering on the IQueryable, this means ordering by the Lucene fields in the index and not the Sitecore Item fields collection. The code looks something like this:

queryable = queryable.OrderBy(x => x[(ObjectIndexerKey)"my_string_field"]);

The above line of code should be all you need to order the queryable. However, it won’t work, not without the right configuration. Instead, you’ll see all of your items in a seemingly random order. A very consistent random order. That’s because it’s not random at all! This is a byproduct of tokenization, since most string fields have spaces in their data values.

How to make sure ordering works the way you expect

In the fieldNames block of the Lucene configuration file, you will need to make sure the field you are ordering by is specified. In addition, an analyzer is needed to ensure it is added to the index documents correctly. The configuration looks like this:

<field fieldName="My String Field" storageType="YES" indexType="UN_TOKENIZED" vectorType="NO" boost="1f" type="System.String" settingType="Sitecore.ContentSearch.LuceneProvider.LuceneSearchFieldConfiguration, Sitecore.ContentSearch.LuceneProvider">
   <analyzer type="Sitecore.ContentSearch.LuceneProvider.Analyzers.LowerCaseKeywordAnalyzer, Sitecore.ContentSearch.LuceneProvider" />
 </field>

Note the indexType value of “UN_TOKENIZED”. This makes sure that the values in the field are treated as a whole, allowing the OrderBy clause to use the entire string for ordering and not the tokens.

Supporting Keyword Searching

If you need to be able to tokenize your field and order by it as well, you’ll need two field definitions in the configuration. A regular tokenized version for searching, and then a separate mapping that will be used for the untokenized version. In this scenario, you’ll search on the tokenized field, but order by the untokenized field in the index.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s