Creating Crawled Properties
June 29, 2010 Leave a comment
You can create crawled properties for search programmatically without needing to start a full crawl. This can be helpful when adding managed properties that map to crawled properties and you can’t be sure the crawled properties will exist at that time. In the following, we create some crawled properties using a manager class and wrap up the logic in a Feature that can be deployed in a solution package.
The first thing we do is create a manager class that adds crawled properties using the object model:
public class CrawledPropertyManager
{
private Schema _schema;
private IEnumerable<CrawledProperty> _crawledProperties;
public CrawledPropertyManager(string serviceName, string applicationName)
{
SPFarm farm = SPFarm.Local;
SearchService searchService = farm.Services.GetValue<SearchService>(serviceName);
SearchServiceApplication searchApp =
searchService.SearchApplications.GetValue<SearchServiceApplication>(applicationName);
_schema = new Schema(searchApp);
_crawledProperties = _schema.QueryCrawledProperties(string.Empty, 1000000, Guid.NewGuid(),
string.Empty, true).Cast<CrawledProperty>();
}
public void AddCrawledProperty(string propertyName, PropertySet propSet, VariantType variant)
{
if (string.IsNullOrEmpty(propertyName))
{
throw new ArgumentNullException("propertyName");
}
propertyName = Settings.GetCrawledPropertyPrefix(propSet) + propertyName;
var crawledProperty = _crawledProperties.FirstOrDefault(c => c.Name.Equals(propertyName));
//only create the crawled property if one doesn't already exist
if (crawledProperty == null)
{
var propSetId = Settings.GetPropertySetId(propSet);
var category = _schema.AllCategories[propSetId];
try
{
category.CreateCrawledProperty(propertyName, false, propSetId, (int)variant);
category.Update();
}
catch (Exception ex)
{
Logging.Logger.Log(ex);
}
}
}
}
Then create a Feature which uses the manager for adding crawled properties one at a time.
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
_properties = properties;
try
{
var manager = new CrawledPropertyManager(
SearchServiceName.EnterpriseSearch,
SearchServiceApplicationName.Default);
manager.AddCrawledProperty(“Property1″, PropertySet.People, VariantType.String);
manager.AddCrawledProperty(“Property2″, PropertySet.People, VariantType.Datetime);
manager.AddCrawledProperty(“Property3″, PropertySet.People, VariantType.Taxonomic);
}
catch (Exception ex)
{
//log exception
}
}
We use a Settings class to factor out the property set and variant types:
public static class Settings
{
public static Guid GetPropertySetId(PropertySet propSet)
{
var retVal = Guid.Empty;
var propSetIdString = string.Empty;
switch (propSet)
{
case PropertySet.Basic:
propSetIdString = PropertySetGuid.Basic;
break;
case PropertySet.Mail:
propSetIdString = PropertySetGuid.Mail;
break;
case PropertySet.Office:
propSetIdString = PropertySetGuid.Office;
break;
case PropertySet.People:
propSetIdString = PropertySetGuid.People;
break;
case PropertySet.SharePoint:
propSetIdString = PropertySetGuid.SharePoint;
break;
}
if (!string.IsNullOrEmpty(propSetIdString))
{
retVal = new Guid(propSetIdString);
}
return retVal;
}
public static string GetCrawledPropertyPrefix(PropertySet propSet)
{
var retVal = string.Empty;
switch (propSet)
{
case PropertySet.People:
retVal = CrawledPropertyPrefix.People;
break;
case PropertySet.SharePoint:
retVal = CrawledPropertyPrefix.SharePoint;
break;
}
return retVal;
}
}
public enum PropertySet
{
Basic,
Mail,
Office,
People,
SharePoint
}
internal struct PropertySetGuid
{
public const string SharePoint = "00130329-0000-0130-c000-000000131346";
public const string Basic = "0b63e343-9ccc-11d0-bcdb-00805fccce04 ";
public const string Mail = "aa568eec-e0e5-11cf-8fda-00aa00a14f93";
public const string Office = "f29f85e0-4ff9-1068-ab91-08002b27b3d9";
public const string People = "00110329-0000-0110-c000-000000111146";
}
internal struct CrawledPropertyPrefix
{
public const string SharePoint = "ows_";
public const string People = "urn:schemas-microsoft-com:sharepoint:portal:profile:";
}
public struct SearchServiceName
{
public const string EnterpriseSearch = "OSearch14";
}
public struct SearchServiceApplicationName
{
public const string Default = "Search Service Application";
}
public enum VariantType
{
String = 31,
YesNo = 11,
Binary = 12,
Integer = 20,
Datetime = 64,
Taxonomic = 4127
}
After deploying the solution and activating our feature the new properties will show up in Central Administration > Search Service Application > Crawled Properties:
Note: nothing has been indexed yet by the search crawler. We must still do a full crawl and add managed properties that map to our crawled properties before we can search. See Creating Managed Properties for creating and mapping managed properties to crawled properties.
You can do the same thing in PowerShell. Here is a great post that describes how to do this: Creating Enterprise Search Metadata Property Mappings with PowerShell.