Friday, May 8, 2009

Managed Property Creator tool

In interface everybody knows to create Managed Properties used by MOSS search. Those can also be created programmatically very simple. This tool is created to be used by the admins on deployment time. Using this tool the admins save time and they are sure that all managed properties were created with no error.

This tool use a configuration file describing the managed properties name, description mapped properties etc. This file must be updated before the tool is used. Here is an example of this file look like:

<MappedProperty>
<Name>TheId</Name>
<Description>My first test</Description>
<UseInScopes>yes</UseInScopes>
<DataType>integer</DataType>
<CrawledProperties>
<CrawledProperty>
<Name>ows_ID</Name>
</CrawledProperty>
</CrawledProperties>
</MappedProperty>



This will create a managed property called “TheId” that will be used in scope search and mapped to the “ows_ID” crawled property. Can be zero, one or more crawled property mapped depending on how much are specified inside the CrawledProperties tag.



Do not forget that a property will be crawled only if contain any data.



For using this tool you have to specify two parameters. First is “-c” or “-d” if you want to create or delete. Second is the name of the configuration file.



Having the code bellow you only have to compile and use.




using System;
using System.Collections.Generic;
using System.Text;

using Microsoft.SharePoint;
using Microsoft.Office.Server;
using Microsoft.Office.Server.Search;
using Microsoft.Office.Server.Search.Administration;
using System.Xml;

namespace ManagedPropertyCreator
{
class Program
{
private static ManagedDataType GetManagedDataType(string strDataType)
{
ManagedDataType returnValue = ManagedDataType.Text;
switch (strDataType)
{
case ("binary"):
returnValue = ManagedDataType.Binary;
break;
case ("datetime"):
returnValue = ManagedDataType.DateTime;
break;
case ("decimal"):
returnValue = ManagedDataType.Decimal;
break;
case ("integer"):
returnValue = ManagedDataType.Integer;
break;
case ("yesno"):
returnValue = ManagedDataType.YesNo;
break;
default:
returnValue = ManagedDataType.Text;
break;
}
return returnValue;
}

private static bool GetUsedInScopes(string isused)
{
if (isused.CompareTo("no") == 0) return false;
else return true;
}

private static Category GetSharePointCategory(Schema sspSchema)
{
CategoryCollection categories = sspSchema.AllCategories;
foreach (Category category in categories)
{
if (category.Name.Contains("SharePoint"))
{
return category;
}
}
return null;
}

private static bool GetUsageMode(string usageMode)
{
if (usageMode == "-c") return true;
else return false;
}

static void Main(string[] args)
{
try
{
if (args.Length != 2)
{
Usage();
return;
}

bool isCreating = GetUsageMode(args[0]);

XmlDocument config_file = new XmlDocument();
config_file.Load(args[1]);
Console.WriteLine("Parsing configuration file... ");

// get the site url
string strURL = config_file.SelectSingleNode("/root/SiteName").InnerXml.ToString().Trim();

SearchContext context;
using (SPSite site = new SPSite(strURL))
{
context = SearchContext.GetContext(site);
if (context != null) Console.WriteLine(String.Format("Connected to {0}...", strURL));
else
{
Console.WriteLine(String.Format("Error : Cannot connect to {0} !", strURL));
return;
}
}
Schema sspSchema = new Schema(context);
ManagedPropertyCollection properties = sspSchema.AllManagedProperties;

// get mapped properties nodes
XmlNode nodeMappedProperties = config_file.SelectSingleNode("/root/MappedProperties");
foreach (XmlNode mpNode in nodeMappedProperties.ChildNodes)
{
string mpName = mpNode.SelectSingleNode("Name").InnerXml.ToString().Trim();
string mpDesc = mpNode.SelectSingleNode("Description").InnerXml.ToString().Trim();
string mpUseInScopes = mpNode.SelectSingleNode("UseInScopes").InnerXml.ToString().Trim();
string mpDataType = mpNode.SelectSingleNode("DataType").InnerXml.ToString().Trim();

// here code for create Managed Property
Console.WriteLine("");
Console.Write(String.Format("{0} <{1}> metadata property", (isCreating)?"Create":"Delete", mpName));
if (properties.Contains(mpName))
{
if (isCreating)
{
Console.WriteLine(String.Format("\nINFO: Managed Property with name <{0}> already exists. Will be skipped...", mpName));
continue; // already exist - skip this one
}
}
else
{
if (!isCreating)
{
Console.WriteLine(String.Format("\nINFO: Managed Property with name <{0}> do not exists. Will be skipped...", mpName));
continue; // do not exist - skip this one
}
}

if (isCreating)
{
ManagedProperty newMP = properties.Create(mpName, GetManagedDataType(mpDataType));
newMP.Description = mpDesc;
newMP.EnabledForScoping = GetUsedInScopes(mpUseInScopes);

MappingCollection mappings = new MappingCollection();
XmlNode mpCrawledProperties = mpNode.SelectSingleNode("CrawledProperties");
// code for map with crawled properties
foreach (XmlNode mpCrawledProperty in mpCrawledProperties.ChildNodes)
{
string nameCrawledProperty = mpCrawledProperty.SelectSingleNode("Name").InnerXml.ToString().Trim();

foreach (CrawledProperty property in GetSharePointCategory(sspSchema).GetAllCrawledProperties())
{
if (property.Name.CompareTo(nameCrawledProperty) == 0)
{
mappings.Add(new Mapping(property.Propset, property.Name, property.VariantType, newMP.PID));
}
}
}
newMP.SetMappings(mappings);

// do not forget to update the new created mapped property
newMP.Update();
}
else
{
foreach (ManagedProperty oldMP in properties)
{
if (oldMP.Name == mpName)
{
if (oldMP.DeleteDisallowed)
{
Console.WriteLine("\n DeleteDisallowed enabled for " + mpName + ". Delete failed.");
continue;
}
oldMP.DeleteAllMappings();
oldMP.Delete();
Console.Write("\n"+mpName + " deleted.");
break;
}
}
}
Console.Write("...OK"); Console.WriteLine("");
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
finally
{
Console.WriteLine("\n All done...press any key");Console.ReadKey();
}

}

static void Usage()
{
Console.WriteLine("Managed Property Creator");
Console.WriteLine("Usage: ManagedPropertyCreator.exe <usage_mod> <conf_file>");
Console.WriteLine("<usage_mod> - Specify if the tool is used to create or delete metadata properties. Acceptev values: -c and -d");
Console.WriteLine("<conf_file> - The file that contain the configuration data.");
}

}
}





And yes, the configuration file:




<?xml version="1.0" encoding="utf-8"?>
<!-- SiteName is the name of the site using the SharedServiceProvider -->
<!-- DataType can be : binary, datetime, decimal, integer, text, yesno -->
<!-- UseInScopes can be : yes or no -->
<root>
<SiteName>http://CF316431:555/ssp/admin</SiteName>
<MappedProperties>
<MappedProperty>
<Name>ManagedProperty1</Name>
<Description>My first test</Description>
<UseInScopes>yes</UseInScopes>
<DataType>text</DataType>
<CrawledProperties>
<CrawledProperty>
<Name>ows_FileLeafRef</Name>
</CrawledProperty>
<CrawledProperty>
<Name>ows_LinkedDocumentField</Name>
</CrawledProperty>
</CrawledProperties>
</MappedProperty>
<MappedProperty>
<Name>ManagedProperty2</Name>
<Description>My first test 2</Description>
<UseInScopes>yes</UseInScopes>
<DataType>text</DataType>
<CrawledProperties>
<CrawledProperty>
<Name>ows_FormulaField</Name>
</CrawledProperty>
</CrawledProperties>
</MappedProperty>
</MappedProperties>
</root>



For using you only have to type



ManagedPropertyCreator.exe –c mpc_config.xml

No comments:

Post a Comment