private static void RebuildMetadataProperties(XNode config, SPServiceContext context) { // Get the search service application proxy var searchProxy = SearchServiceApplicationProxy.GetProxy(context); // Another alternative is the following line ;) // * var searchProxy = // context.GetDefaultProxy(typeof (SearchServiceApplicationProxy)) as SearchServiceApplicationProxy; if (searchProxy == null) { throw new InvalidOperationException("Search Service Application was not found."); } // Get the search service application info object so we can find the Id of // our Search Service Application. var ssai = searchProxy.GetSearchServiceApplicationInfo(); // Get the application itself var searchApp = SearchService.Service.SearchApplications.GetValue <SearchServiceApplication>(ssai.SearchServiceApplicationId); // Get the schema of our Search Service Application var schema = new Schema(searchApp); var crawledPropsCache = new List <CrawledProperty>(); var categories = schema.AllCategories; // Remove Managed Properties var managedPropsRemove = config.XPathSelectElements("/SearchConfiguration/ManagedProperties/remove"); RemoveManagedProperties(schema, managedPropsRemove); var loadedCategories = new HashSet <string>(); // Add / update crawled properties under different categories // SearchConfiguration > CrawledProperties > Category foreach (var categoryCfg in config.XPathSelectElements("/SearchConfiguration/CrawledProperties/Category")) { // If crawled properties in this category are not loaded // load them and add category name to the list. var categoryName = TryGetAttributeValue(categoryCfg, "Name"); if (string.IsNullOrEmpty(categoryName)) { Logger.LogMessage(SeverityLevels.Critical, LogCategory, string.Format(CategoryAttributeMissingLogFormat, "Name")); continue; } var cat = categories[categoryName]; if (!loadedCategories.Contains(categoryName)) { crawledPropsCache.AddRange(categories[categoryName].GetAllCrawledProperties().Cast <CrawledProperty>()); loadedCategories.Add(categoryName); } // SearchConfiguration > CrawledProperties > Category > * (clear | CrawledProperty) foreach (var crawledPropCfg in categoryCfg.Elements()) { if (crawledPropCfg.Name == "clear") { ClearCrawledPropertiesInCategory(crawledPropsCache, cat, categoryCfg); } else if (crawledPropCfg.Name == "CrawledProperty") { // Create the crawled property if it doesn't exist CreateCrawledPropertyIfDoesNotExist(crawledPropsCache, cat, crawledPropCfg); } } } // Get all the managed properties // Create all required managed properties // SearchConfiguration > ManagedProperties > ManagedProperty // foreach (var managedPropCfg in config.Element("SearchConfiguration").Element("ManagedProperties").Elements("ManagedProperty")) foreach (var managedPropCfg in config.XPathSelectElements("/SearchConfiguration/ManagedProperties/ManagedProperty")) { var managedPropName = TryGetAttributeValue(managedPropCfg, "Name"); if (string.IsNullOrEmpty(managedPropName)) { Logger.LogMessage(SeverityLevels.Critical, LogCategory, string.Format(UnknownManagedPropertyAttributeMissingLogFormat, "Name")); continue; } var managedPropType = TryGetAttributeValue(managedPropCfg, "Type"); if (string.IsNullOrEmpty(managedPropType)) { Logger.LogMessage(SeverityLevels.Critical, LogCategory, string.Format(KnownManagedPropertyAttributeMissingLogFormat, managedPropName, "Type")); continue; } var managedProp = CreateOrGetManagedProperty(schema, managedPropName, managedPropType); // Create all the required mappings for the current Managed Property var isMappingChanged = false; MappingCollection mappings = null; foreach (var mapCfg in managedPropCfg.Elements()) { if (mapCfg.Name == "clear") { // Clear all mappings of this ManagedProperty managedProp.DeleteAllMappings(); isMappingChanged = true; } else if (mapCfg.Name == "Map") { // Add new mappings mappings = managedProp.GetMappings(); var crawledPropName = mapCfg.Value; var mappingCategoryName = TryGetAttributeValue(mapCfg, "Category"); var crawledProp = FindCrawledProperty(schema, crawledPropName, mappingCategoryName, crawledPropsCache, loadedCategories); // Map the managed property to the crawled property (if found) if (crawledProp != null) { var mapping = new Mapping( crawledProp.Propset, crawledPropName, crawledProp.VariantType, managedProp.PID); if (!mappings.Contains(mapping)) { mappings.Add(mapping); isMappingChanged = true; } } else { Logger.LogMessage(SeverityLevels.Critical, LogCategory, string.Format(PropertyMappingFailedExceptionFormat, managedPropName)); } } } if (isMappingChanged) { managedProp.SetMappings(mappings); } } }