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 anAuthor
item - an
Author
item (I felt lazy and created only one) - an index field called
AuthorPublications
which is computed for all items derived from theAuthor
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
.
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:
Pingback: Tagging is fun in Sitecore | Visions In Code
Thanks Uli, just got it working.
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 🙂
Nice Explanation
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.
Hi, I haven’t worked on Sitecore for a year so can’t help you unfortunately.
Pingback: Creating Computed Index field in Sitecore 8 – appdevsitecore
Good one!!
Hi Uli, got a question, where have you declared and defined the other two field properties, AuthorGivenName and AuthorFamilyName?
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.
Hello Uli,
As you mention to use App_Config/Include/Sitecore.ContentSearch.Lucene.DefaultIndexConfiguration.config
but I am using solr index, so which file do I have to use for configuration
Regards,
Phanuwat
As far as I remember the file name is “App_Config/Include/Sitecore.ContentSearch.Solr.DefaultIndexConfiguration.config”.
Pingback: Creating Computed Index field in Sitecore 8 - crackitinterview.com