Examiness hints and tips from the trenches part 10 - Document writing redux


Just a quick post showing another use for the document writing event. When it comes to working with Umbraco Examine I take the lazy 'index all' approach when it comes to fields. So in my ExamineIndex.config I do not have IndexUserFields node therefore Examine will add all the fields.  However once or twice I have been caught out by this approach. Bascially after setting up the index there has been a requirement to sort by a non standard field e.g ArticleDate.  So in the past I have had to go back and add all the fields then enable sorting on that one field e.g

      <add Name="firstName" />
      <add Name="lastName" />
      <add Name="roleName" />
     <add Name="ArticleDate" EnableSorting="true"/>

However there is a quick work around for this. You can inject in the sortable field using Document writing event:

var indexer = (UmbracoContentIndexer)ExamineManager.Instance.IndexProviderCollection[MyIndex];

indexer.DocumentWriting += indexer_DocumentWriting;

/// <summary>
/// used to get low level lucene document access
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void indexer_DocumentWriting(object sender, Examine.LuceneEngine.DocumentWritingEventArgs e)

for article doc types we need to inject in sortable article date or use update date
directly into lucene this saves us having to mess around with examineindex.config where you have to put in
each field then on field u want to sort put in sortable attribute
if (DocTypeHasArticleDateForSorting(e))
DateTime articleDate;
if (e.Fields.ContainsKey(DocumentType.Article.ArticleDate))
articleDate = DateTime.Parse(e.Fields[DocumentType.Article.ArticleDate]);
articleDate = DateTime.Parse(e.Fields["updateDate"]);
// in __Sort_articleDate the __ implies is not analysed therefore can be used to sorting. sorted means its retrievable
//see page 43 lucene in action 2nd edition for full explanation of options
var field = new Field("__Sort_articleDate", articleDate.ToString("yyyyMMddHHmmss", CultureInfo.InvariantCulture), Field.Store.YES, Field.Index.NOT_ANALYZED);