Monday, October 15, 2012

PowerShell HowTo: Creating managed properties and adding crawled properties

In the previous posts I showed how you deploy a Custom Indexing Connector (or Search Connector) to SharePoint and how you create a content source that makes use of it.

In this post I will give a quick introduction to Crawled Properties and explain how to create a new Managed Property using PowerShell as well as how to add crawled properties to it.

Where do crawled properties come from?

I won't go into the definition of Managed Properties and Crawled Properties, you can bing that for yourself. But I show you where crawled properties come from (with a custom indexing connector in mind).

Why do I want to know?

You need crawled and managed properties to improve the search experience for your users.

After setting up the indexing connector you need to start a crawl on your external system (if you didn't already do it: start it now and check the Crawl Log for success). The connector will index content it finds (so your users can search for it) and it will create Crawled Properties. These come from your BDC.

So let's keep in mind that we want to improve the search experience. And this can be done by creating Search Refiners centered around BDC entities. And we ultimately need those crawled properties to do this.

It's in the BDC

Let's assume you are crawling a financial LOB system and your BDC model file contains an entity Order which has the following structure:
<TypeDescriptor Name="Order" TypeName="PurchasingConnector.Entities.Order, PurchasingConnector, Version=1.0.0.0, Culture=neutral, PublicKeyToken=0000000000000000">
  <TypeDescriptors>
    <TypeDescriptor Name="OrderNo" TypeName="System.String" IdentifierEntityNamespace="Purchasing" IdentifierEntityName="Order" IdentifierName="OrderNo" />
    <TypeDescriptor Name="Customer" TypeName="System.String" />
    <TypeDescriptor Name="OrderDate" TypeName="System.DateTime" />
  </TypeDescriptors>
</TypeDescriptor>
After doing the first full crawl on your external system your list of crawled properties should have been expanded. Have a look - go to Central Administration -> Search Service Application -> Queries and Results -> Metadata Properties:

Search Service Application - Metadata Properties

In the top menu click Crawled Properties:

This will list all crawled properties including these from your BDC:
  • Order.OrderNo(Text)
  • Order.Customer(Text)
  • Order.OrderDate(Date and Time)
(You probably have to search a bit as they hide among the masses of OOB crawled properties.)

Refiners the way we want them

Ultimately, we want to create a refiner allowing us to filter for the customer of an order.
Search Refiner

To do this we need a managed property (as the tutorials on creating search refiners will tell you). And that is exactly what we're going to created now using PowerShell: a managed property.

Time to create Managed Properties and add Crawled Properties

To stick with the above example we create a managed property named Customer:
$ssaGlobal = Get-SPEnterpriseSearchServiceApplication
$schemaGlobal = New-Object -TypeName Microsoft.Office.Server.Search.Administration.Schema -ArgumentList $ssaGlobal

# check if property already exists - in this case we cancel the operation
$property = GetManagedProperty -ssa $ssaGlobal -schema $schemaGlobal -managedPropertyName "Customer"
if ($property)
{
    Write-Host -f Red "Cannot create managed property because it already exists"
 exit
}

# create managed property with name "Customer" of type "Text"
$property = $schemaGlobal.AllManagedProperties.Create("Customer", "Text")
# set description; there are other properties you could set here
$property.Description = "Customer of Order (Managed Property created from PowerShell)"
That's basically it. But the managed property is still empty. We need to add a mapping for our crawled property. Here is how:
# this is the "Property Set GUID"; it is also used by the custom indexing connector so this is where you need to get it from
$propSetGuidGlobal = "{00000000-0815-0000-0000-000000000000}"
$textVariantType = 31
$mappings = $property.GetMappings();

# try to map crawled property - if the crawled properties doesn't exist nothing bad happens, it will simply be ignored
$mapping = New-Object -TypeName Microsoft.Office.Server.Search.Administration.Mapping -ArgumentList $propSetGuidGlobal, "Order.Customer", $textVariantType, $property.PID
$mappings.Add($mapping)
 
$property.SetMappings($mappings)
$property.Update()
Note that you need to specify the Property Set GUID for the Property Set the crawled property is contained in. For the OOB crawled properties in SharePoint these are documented (somewhere). For a custom indexing connector this ID is defined inside the connector. So this information should probably be contained in the documentation for ease of use.

Also note the type of the crawled property, 31, which means Text. This and more variant type identifiers are listed in this blog post.

Now go and crawl!

After creating or modifying managed properties you have to do a full crawl. Otherwise your managed property won't work as expected.

No comments:

Post a Comment