Creating Managed Properties

Managed properties for search can be created using a feature and they can be mapped to crawled properties. See Creating Crawled Properties for setting up your crawled properties first without needing to run a full crawl during deployment. Managed properties have to be set up before you can query on any metadata field (SharePoint, People, Mail, etc.).

In order to be able to manage the creation of managed properties and how they get mapped to crawled properties we created a manager class. When this class gets instantiated it creates a reference to the specified search service and search service application on the local farm.

image

Once we have a reference to the service application we can store the search schema in a private field. The Schema  holds all of the crawled, managed, and mapped properties needed for search.

image 

From the schema we can get collections of all the crawled and managed properties and store them in private fields in our manager as well.

image

Then, once the manager has been instantiated, the add method can be called repeatedly to add a series of properties. If the property already exists we retrieve it for updating it’s mappings to crawled properties. If the retrieved property already has mappings we remove those that match the current managed property name in order to update them from scratch.

    /// <summary>
    /// A manager for adding and updating managed properties for Enterprise Search.
    /// </summary>
    public class ManagedPropertyManager
    {
        private Schema _schema;
        private IEnumerable<CrawledProperty> _crawledProperties;
        private ManagedPropertyCollection _allManagedProperties;

        public ManagedPropertyManager(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>();
            _allManagedProperties = _schema.AllManagedProperties;
        }

        /// <summary>
        /// Adds a managed property for search that is mapped to the specified crawled property.
        /// An exception is thrown if the crawled property is not found.
        /// </summary>
        /// <param name="propertyName">The name of the managed property.</param>
        /// <param name="propSet">The crawled property's property set for which a mapping is being added.</param>
        /// <param name="dataType">The data type of the managed property.</param>
        public void AddPropertyWithMapping(string propertyName, PropertySet propSet, ManagedDataType dataType)
        {
            if (string.IsNullOrEmpty(propertyName))
            {
                throw new ArgumentNullException("propertyName");
            }

            ManagedProperty property = null;

            if (_allManagedProperties.Contains(propertyName))
            {
                property = _allManagedProperties[propertyName];
            }
            else
            {
                try
                {
                    property = _allManagedProperties.Create(propertyName, dataType);
                }
                catch (Exception ex)
                {
                    //log exception
                }
            }

            if (property != null)
            {
                var mappings = property.GetMappings();
                var crawledPropertyName = Settings.GetCrawledPropertyPrefix(propSet) + propertyName;
                var crawledProperty = _crawledProperties.FirstOrDefault(c => c.Name.Equals(crawledPropertyName));

                if (crawledProperty != null)
                {
                    for (int i = 0; i < mappings.Count; i++)
                    {
                        if (string.Compare(mappings[i].CrawledPropertyName, crawledProperty.Name, true) == 0)
                        {
                            mappings.Remove(mappings[i]);
                        }
                    }

                    var mapping = new Mapping(
                        crawledProperty.Propset,
                        crawledProperty.Name,
                        crawledProperty.VariantType,
                        property.PID);

                    if (!mappings.Contains(mapping))
                    {
                        mappings.Add(mapping);
                        property.SetMappings(mappings);
                        property.Update();
                    }
                }
                else
                {
                    //throw exception
                }
            }
            else
            {
                //throw exception
            }
        }
    }

The ManagedPropertyManager can then be used in a feature receiver to provision managed properties on deployment.

public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
    _properties = properties;

    try
    {
        var manager = new ManagedPropertyManager(
            SearchServiceName.EnterpriseSearch,
            SearchServiceApplicationName.Default);

        manager.AddPropertyWithMapping("Property1", PropertySet.SharePoint, ManagedDataType.Text);
        manager.AddPropertyWithMapping("Property2", PropertySet.Mail, ManagedDataType.YesNo);
        manager.AddPropertyWithMapping("Property3", PropertySet.People, ManagedDataType.DateTime);
    }
    catch (Exception ex)
    {
        //log exception
    }
}

After the feature has finished activating, you will see your properties in the Metadata Properties list in Central Administration.

image

And if you click on the property name you can view and change it’s settings. The mappings to the crawled properties will also be displayed on this page (the AboutMe property is displayed below).

image

Follow

Get every new post delivered to your Inbox.