Computed Index Fields – Sitecore 7 Content Search

Reason

Sometimes the information you’d like to run a Sitecore Content Search query against isn’t readily available via the items you’re trying to retrieve, e.g. information stored somewhere else in the Sitecore content tree or not stored in Sitecore at all. This can result in complex queries or require you to mix Linq-to-Sitecore with Linq-to-objects which lowers performance.
Computed index fields can in some cases be used to circumvent such issues by storing the required information in a more “query friendly” manner as outlined below.

Examples are based on Sitecore CMS 7.1 Update-1 (rev. 140130).

Code

To implement a computed index field the following is required:

  • Create a class which implements Sitecore.ContentSearch.ComputedFields.IComputedIndexField.
  • Create a config-include file which adds the computed index field to the index configuration.

In the following example an index field called AuthorPublications is implemented and configured. The example uses…

  • several Publication items, each having a reference to an Author item
  • an Author item (I felt lazy and created only one)
  • an index field called AuthorPublications which is computed for all items derived from the Author template, existing only in the index and containing the IDs of all publications associated with the author

The Author and Publication templates are set up as shown below. The main point to note is that the Author item template doesn’t contain a field called AuthorPublications.

Author sample item

Author sample item

Publication sample item

Publication sample item

The code shown below is the IComputedIndexField implementation itself. The properties FieldName and ReturnType are set based on the configuration shown later and in this case serve no other purpose than being required by the interface.

using System;
using System.Collections.Generic;
using System.Linq;
using Sitecore;
using Sitecore.ContentSearch;
using Sitecore.ContentSearch.ComputedFields;
using Sitecore.Data.Items;

public class AuthorPublications : IComputedIndexField
{
  public object ComputeFieldValue(IIndexable indexable)
  {
    Item item = indexable as SitecoreIndexableItem;
    if (item == null)
      return null;
    if (item.TemplateName != "Author")
      return null;
    return GetPublicationIDs(item);
  }

  private IEnumerable<Guid> GetPublicationIDs(Item authorItem)
  {
    return (from link in Globals.LinkDatabase.GetItemReferrers(authorItem, false)
            let sourceItem = link.GetSourceItem()
            where sourceItem != null
            where sourceItem.TemplateName == "Publication"
            select sourceItem.ID.Guid).ToArray();
  }

  public string FieldName
  {
    get;
    set;
  }

  public string ReturnType
  {
    get;
    set;
  }
}

Shown below is the Author class which can be used in Linq-to-Sitecore queries, including a property configured to match the AuthorPublications computed index field.

using System;
using System.Collections.Generic;
using Sitecore.ContentSearch;

public class Author
{
  [IndexField("AuthorGivenName")]
  public string GivenName
  {
    get;
    set;
  }

  [IndexField("AuthorFamilyName")]
  public string FamilyName
  {
    get;
    set;
  }

  [IndexField("AuthorPublications")]
  public IEnumerable<Guid> Publications
  {
    get;
    set;
  }
}

The configuration shown below sets up the computed index field – save it in a .config-file in a subfolder of “App_Config/Include/” (e.g. “App_Config/Include/MyCompany/ComputedIndexFields.config”). Modify namespace and assembly names as needed.

<?xml version="1.0" encoding="utf-8" ?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <contentSearch>
      <configuration>
        <defaultIndexConfiguration>
          <fields hint="raw:AddComputedIndexField">
            <field fieldName="AuthorPublications" storageType="YES" indexType="TOKENIZED">NamespaceName.AuthorPublications, AssemblyName</field>
          </fields>
        </defaultIndexConfiguration>
      </configuration>
    </contentSearch>
  </sitecore>
</configuration>

When creating configurations for your own computed index fields, I suggest using “App_Config/Include/Sitecore.ContentSearch.Lucene.DefaultIndexConfiguration.config” for inspiration.

Example

Shown below is a screenshot from Luke showing the indexed data:
Luke screenshot

10 thoughts on “Computed Index Fields – Sitecore 7 Content Search

  1. Pingback: Tagging is fun in Sitecore | Visions In Code

    • Hi Mark,

      You’re comment included some markup which WordPress apparently wasn’t happy with, I assume it’s related to the content search configuration changes in Sitecore 7.2 and later.
      This article was written based on Sitecore CMS 7.1 Update-1 (rev. 140130) and I haven’t come back to update the config include file – if you can try to post the updated version again I’d be grateful 🙂

  2. Hi Uli,
    I am using Sitecore8.1 and implemented your code. However I am unable to see the “AuthorPublications” in Luke. In which Index folder I need to look and what is the default field I need to use in search.

  3. Pingback: Creating Computed Index field in Sitecore 8 – appdevsitecore

    • Hi Nataraj,

      The two fields aren’t configured explicitly in the index if that’s what you mean, most solutions I worked on back then simply had indexing turned on for all fields by default.

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