Index Searching - Find-Item using custom fields with Sitecore Powershell


UPDATE: Michael West likes this solution and confirmed that it will be part of the next release of SPE (6.0), becoming my first contribution to SPE! Here is the ticket where this implementation is being tracked.


If you are a big fan of Sitecore Powershell Extensions like me, you probably know the Find-Item command, which allows searching your search index in Powershell scripts. This command, however, has an important limitation: you cannot use custom fields to filter and sort from the index. Due to this limitation, extended usage of Find-Item with custom code is usually not possible.

Internally Find-Item uses the base class “Sitecore.ContentSearch.SearchTypes.SearchResultItem“, which does not include any custom fields. What we usually do with C# is to create a class that inherits from “SearchResultItem“, adding our custom fields, such as below:

public class CustomSearchResultItem : SearchResultItem
{
   [IndexField("_templates")]
   [DataMember]
   public virtual List<ID> TemplateIds { get; set; }
}

The Find-Item command, however, does not allow using this field. For instance, the following script:

$props = @{
 Index = "sitecore_master_index"
 Where = "Paths.Contains(@0) And TemplateIds.Contains(@1)"
 WhereValues = [ID]::Parse("{D5B8857B-DE30-4616-84F5-812A7129ACD5}"), [ID]::Parse("{50FFE147-4F48-428B-A417-4D96DD2048FF}")
}
Find-Item @props

Will give the following error:

Find-Item : No property or field 'TemplateIds' exists in type 'SearchResultItem'

Because, yeah… that property is only defined at our custom class, not at SearchResultItem. To circumvent this limitation I built this special command.

Find-CustomItem

This command extends the original Find-Item, allowing you to pass a type that will be used instead of the base SearchResultItem class:

$props = @{
 Index = "sitecore_master_index"
 Type = [PSWebsite.Foundation.Indexing.SearchTypes.BaseSearchResultItem]
 Where = "Paths.Contains(@0) And TemplateIds.Contains(@1)"
 WhereValues = [ID]::Parse("{D5B8857B-DE30-4616-84F5-812A7129ACD5}"), [ID]::Parse("{50FFE147-4F48-428B-A417-4D96DD2048FF}")
}
Find-CustomItem @props

Create the custom command

In order to use Find-CustomItem in your project, you should:

  1. Add NuGet references to Sitecore.ContextSearch and Sitecore.ContextSearch.Linq;
  2. Add a reference to Cognifide.Powershell.dll;
  3. Create a custom FindItemCommand class extending Cognifide.PowerShell.Commandlets.Data.Search.FindItemCommand;
    You can download the whole class here
  4. Register your new command with an include patch – make sure the content is according to the following
<?xml version="1.0"?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
   <sitecore>
      <powershell>
         <commandlets>
            <add Name="Find Item" type="PSWebsite.Foundation.Indexing.Powershell.Commandlets.FindItemCommand, PSWebsite.Foundation.Indexing" />
         </commandlets>
      </powershell>
   </sitecore>
</configuration>

Limitations

Not all parameters from Find-Item are supported by Find-CustomItem. If you use any of the unsupported parameters along with any custom properties, it will cast the query to the base SearchResultItem, and give the same error as the original Find-Item command.

Supported parameters:

  • Index
  • Where
  • WhereValues
  • OrderBy
  • First
  • Last
  • Skip

Unsupported parameters:

  • Criteria
  • Predicate
  • ScopeQuery

 

Posted in Powershell, SPE

Leave a Reply

Your email address will not be published. Required fields are marked *

*

  Am Not Spammer

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>