Saturday, March 14, 2015

Create managed properties and map to crawl properties programmatically using a feature

This is the second part of the article series, regarding explicitly creating crawl properties and later map in to managed properties.

In this article I will show how to create managed properties and map to explicitly created crawl properties using a custom feature.

1. Create classes for managed property and crawl property collections

  1. public class CrawlPropertyInfo
  2. {
  3.     public string Category { get; set; }
  4.     public string Name { get; set; }
  5.     public ManagedDataType Type { get; set; }
  6. }
  7.  
  8. public class ManagedPropertyInfo
  9. {
  10.     public string ManagedPropertyName { get; set; }
  11.     public ManagedDataType Type { get; set; }
  12.     public string Description { get; set; }
  13.     public List<CrawlPropertyInfo> CrawledProperties { get; set; }
  14. }

2. Create method to map crawl properties to managed properties

  1. public static void SetManagedPropMappings(List<ManagedPropertyInfo> managedPropertyList)
  2. {
  3. try
  4. {
  5.     SPServiceContext serviceContext =
  6.         SPServiceContext.GetContext
  7.         (SPServiceApplicationProxyGroup.Default, SPSiteSubscriptionIdentifier.Default);
  8.  
  9.     var searchProxy =  serviceContext.GetDefaultProxy(typeof(SearchServiceApplicationProxy))
  10.         as SearchServiceApplicationProxy;    
  11.  
  12.     SearchServiceApplicationInfo info = searchProxy.GetSearchServiceApplicationInfo();
  13.  
  14.     SearchServiceApplication application = SearchService.Service.SearchApplications.
  15.     GetValue<SearchServiceApplication>(info.SearchServiceApplicationId);
  16.  
  17.     SearchObjectOwner searchOwner = new SearchObjectOwner(SearchObjectLevel.Ssa);
  18.     Schema schema = new Schema(application);
  19.  
  20.     ManagedPropertyCollection properties = schema.AllManagedProperties;
  21.  
  22.     foreach (ManagedPropertyInfo managedPropertyInfo in managedPropertyList)
  23.     {
  24.         var prop = from pr in schema.AllManagedProperties
  25.                     where pr.Name == managedPropertyInfo.ManagedPropertyName
  26.                     select pr;
  27.  
  28.         ManagedProperty currentProperty = null;
  29.         //create if managed property is null
  30.         if (null == prop || prop.Count() == 0)
  31.         {
  32.             currentProperty = properties.Create(managedPropertyInfo.ManagedPropertyName, managedPropertyInfo.Type);
  33.         }
  34.  
  35.         foreach (CrawlPropertyInfo crawledProperty in managedPropertyInfo.CrawledProperties)
  36.         {
  37.             List<CrawledPropertyInfo> crawledProperties = application.GetAllCrawledProperties(crawledProperty.Name, crawledProperty.Category, 0, searchOwner);
  38.  
  39.             if (prop != null || prop.Count() > 0)
  40.             {
  41.                 currentProperty = prop.First();
  42.                 CrawledPropertyInfo ci = crawledProperties[0];
  43.                 MappingCollection mpc = currentProperty.GetMappings();
  44.  
  45.                 int i;
  46.                 for (i = mpc.Count - 1; i >= 0; i--)
  47.                 {
  48.                     mpc.RemoveAt(i);
  49.                 }
  50.                 currentProperty.Update();
  51.  
  52.                 Mapping map = new Mapping();
  53.                 map.CrawledPropertyName = ci.Name;
  54.                 map.CrawledPropset = ci.Propset;
  55.                 map.ManagedPid = currentProperty.PID;
  56.                 mpc.Add(map);
  57.                 currentProperty.SetMappings(mpc);
  58.                 currentProperty.Update();
  59.             }
  60.         }
  61.     }
  62. }
  63. catch (Exception ex)
  64. {
  65.     //handle error
  66. }
  67. }

3. From the feature activated in feature receiver, call above method with managed properties

  1. public override void FeatureActivated(SPFeatureReceiverProperties properties)
  2. {
  3.     SPSite site = properties.Feature.Parent as SPSite;
  4.     if (null != site)
  5.     {
  6.         List<ManagedPropertyInfo> managedPropertyList = new List<ManagedPropertyInfo>();
  7.         ManagedPropertyInfo testProperty = new ManagedPropertyInfo
  8.         {
  9.             ManagedPropertyName = "TestManagedProperty",
  10.             Type = ManagedDataType.Text,
  11.             CrawledProperties = new List<CrawlPropertyInfo> {
  12.                     new CrawlPropertyInfo{
  13.                         Name = "ows_TestCrawlProperty",
  14.                         Category = "SharePoint",
  15.                         Type = ManagedDataType.Text
  16.                     }
  17.             }
  18.         };
  19.  
  20.         managedPropertyList.Add(testProperty);
  21.         SetManagedPropMappings(managedPropertyList);
  22.     }
  23. }

4. After activating the feature you can see a managed property is created and mapped to a crawl property

image

Wednesday, March 4, 2015

SharePoint 2013 – Create custom Crawl Properties using PowerShell

Sometimes we need to create, custom site columns and some search related logic which requires above columns as managed properties within the same SharePoint solution (WSP). But as we all aware, following steps need to be done to map site columns to managed properties.
image
How can we do this without full crawl ?

As a solution, I create crawl properties using PowerShell prior to the solution deployment. Using the SharePoint solution I create managed properties and map them to crawl properties. Then after sometime, we can run full crawl to finish the process.

I split the article in to two section, to make it clear.
In this post I’ll discuss about creating Crawl Properties using PowerShell. Following are the steps used to create crawl properties

1. Get value for property set parameter from existing category. In my case I added the property to SharePoint category
  1. $searchapp = Get-SPEnterpriseSearchServiceApplication
  2. $cat = Get-SPEnterpriseSearchMetadataCategory -SearchApplication $searchapp -Identity SharePoint
  3. Get-SPEnterpriseSearchMetadataCrawledProperty -SearchApplication $searchapp -Category $cat -Limit 1

I got “00130329-0000-0130-c000-000000131346” as the result

2. Determine Crawl Property names
If your site column is ClientName, then the Crawl Property name will be ows_ClientName

3. Create Crawl Property using PowerShell
  1. New-SPEnterpriseSearchMetadataCrawledProperty -Category SharePoint -IsNameEnum $false -Name "ows_CustomClientName" -PropSet "00130329-0000-0130-c000-000000131346" -SearchApplication $searchapp -VariantType 72
  2.  
  3. New-SPEnterpriseSearchMetadataCrawledProperty -Category SharePoint -IsNameEnum $false -Name "ows_CustomProperty" -PropSet "00130329-0000-0130-c000-000000131346" -SearchApplication $searchapp -VariantType 72
  4.  
  5. New-SPEnterpriseSearchMetadataCrawledProperty -Category SharePoint -IsNameEnum $false -Name "ows_CustomCountry" -PropSet "00130329-0000-0130-c000-000000131346" -SearchApplication $searchapp -VariantType 72

4. That will create Crawl Properties in Search schema
image