I’ve wanted to create this blogpost for a while. It’s kind of a follow-up on my old post on defining a custom index in Sitecore 7 and utilizing it

I’ve been playing around with the index definitions to find out exactly what it takes to create a custom index, with the least amount of configuration possible. The old blogpost was aimed for Sitecore 7.0, initial release, and a lot has happened to the indexes over the latest updates.

This is aimed at the current release of Sitecore 7.2, rev 140526.

You need two things in your config files to create an index, as always I would recommend reading the official manual at Sitecore Developer Network (http://sdn.sitecore.net/upload/sitecore7/70/sitecore_search_and_indexing_guide_sc70-a4.pdf)

  1. The index definition
  2. The index configuration

The index definition

This is where the index is defined, and most of the basic configuration is done. This is what will enable Sitecore to notice that a new index is present, and that is should be visible in the indexing manager.

This node should be placed in configuration/sitecore/contentSearch section of the web.config (or patched)

<configuration type="Sitecore.ContentSearch.ContentSearchConfiguration, Sitecore.ContentSearch">
  <indexes hint="list:AddIndex">
    <index id="myindex_master" type="Sitecore.ContentSearch.LuceneProvider.LuceneIndex, Sitecore.ContentSearch.LuceneProvider">
      <param desc="name">$(id)</param>
      <param desc="folder">$(id)</param>
      <!-- This initializes index property store. Id has to be set to the index id -->
      <param desc="propertyStore" ref="contentSearch/databasePropertyStore" param1="$(id)" />
      <configuration ref="contentSearch/indexConfigurations/mySearchConfiguration" />
      <strategies hint="list:AddStrategy">
        <!-- NOTE: order of these is controls the execution order -->
        <strategy ref="contentSearch/indexUpdateStrategies/syncMaster" />
      </strategies>
      <commitPolicyExecutor type="Sitecore.ContentSearch.CommitPolicyExecutor, Sitecore.ContentSearch">
        <policies hint="list:AddCommitPolicy">
          <policy type="Sitecore.ContentSearch.TimeIntervalCommitPolicy, Sitecore.ContentSearch" />
        </policies>
      </commitPolicyExecutor>
      <locations hint="list:AddCrawler">
        <crawler type="Sitecore.ContentSearch.SitecoreItemCrawler, Sitecore.ContentSearch">
          <Database>master</Database>
          <Root>/sitecore/content/Home</Root>
        </crawler>
      </locations>
    </index>
  </indexes>
</configuration>

The important parts of the configuration is what indexing strategy you want to use. In this case, I’ve used syncMaster as it only looks at the master database, you should use onPublishAsync if you are using a web database index. The second important thing is the locations element. This defines where the index should start crawling, and which database. The final important thing is the configuration element. I’ve set this to a ref to a custom configuration that ill define in the following.

Index configuration

The Index configuration contains the definition about what fields should be indexed, and how. If you simply want to index all the same fields as Sitecores built-in indexes, you should point your index definition to contentSearch/indexConfiguration/defaultLuceneIndexConfiguration. In this example ill use the absolute minimum of configuration for it to work properly:

<mySearchConfiguration type="Sitecore.ContentSearch.LuceneProvider.LuceneIndexConfiguration, Sitecore.ContentSearch.LuceneProvider">
  <indexAllFields>false</indexAllFields>
  <initializeOnAdd>true</initializeOnAdd>
  <analyzer ref="contentSearch/indexConfigurations/defaultLuceneIndexConfiguration/analyzer" />
  <fieldMap type="Sitecore.ContentSearch.FieldMap, Sitecore.ContentSearch">
    <fieldNames hint="raw:AddFieldByFieldName">
      <field fieldName="_uniqueid"            storageType="YES" indexType="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>
    </fieldNames>
  </fieldMap>
  <fieldReaders ref="contentSearch/indexConfigurations/defaultLuceneIndexConfiguration/fieldReaders"/>
  <indexFieldStorageValueFormatter ref="contentSearch/indexConfigurations/defaultLuceneIndexConfiguration/indexFieldStorageValueFormatter"/>
  <indexDocumentPropertyMapper ref="contentSearch/indexConfigurations/defaultLuceneIndexConfiguration/indexDocumentPropertyMapper"/>
</mySearchConfiguration>

The configuration should be added to the configuration/contentSearch/indexConfiguration element.

The important things in the configuration is the element indexAllFields, which is set to false. This will ensure that only the fields we define will be added to the index. Second important element is the AddFieldByFieldName element, which contains the field _uniqueid. This is required, as the index won’t update properly if this field is missing. The remaining elements references the defaultLuceneIndexConfiguration.

With this definition, you’ll get the index up and running, with the absolute minimum. It’s important to notice that we haven’t defined any fields, but the index will contain some. These are added by default by Sitecore, and they are:

  • _content
  • _created
  • _creator
  • _database
  • _datasource
  • _displayname
  • _editor
  • _fullpath
  • _group
  • _indexname
  • _language
  • _latestversion
  • _name
  • _parent
  • _path
  • _template
  • _templatename
  • _uniqueid
  • _updated
  • _version

Using the index

You will be able to use the index using Linq2Sitecore (or what we ended up calling it), but the default SearchResultItem, will have some properties that cannot be accessed, i.e. createdby, url and site.

Retrieving all items from the index could be done like this:

var indexName = "myindex_master";
using (var context = ContentSearchManager.GetIndex(indexName).CreateSearchContext())
{
    var query = context.GetQueryable<SearchResultItem>();

    myListview.DataSource = query.ToList();
    myListview.DataBind();
}

That’s it, the smallest possible configuration to get you own custom-tailored index, that contains the fewest possible fields. I’ll try to blog a little more on defining indexes and using them more advanced in the future.

MySearch.config (3.43 kb)