Friday, September 26, 2014

How To: Query the Office Graph using CSOM

I’m in the process of adding GQL support to the SharePoint 2013 Search Query Tool together with Barry Waldbaum (Microsoft), and while writing the POST support I found it easier to test it using CSOM.

image

Below is sample code with inline comments if you want to go the CSOM route instead of using REST to query the Office graph. The key is to use the Properties property of the KeywordQuery object.

The benefit of using CSOM over REST in my opinion is that you can pass in more than one query per call, and thus optimize network traffic and wire chatter.

Here goes, and take a look at http://msdn.microsoft.com/en-us/library/office/dn783218(v=office.15).aspx for sample GQL queries.

private static void Main(string[] args)
{
var targetSite = new Uri("https://delve.sharepoint.com");
string login = "mikael.svenson@puzzlepart.com";
string password = "use your own";
var securePassword = new SecureString();
foreach (char c in password) { securePassword.AppendChar(c); }
var onlineCredentials = new SharePointOnlineCredentials(login, securePassword);

using (var clientContext = new ClientContext(targetSite))
{
clientContext.Credentials = onlineCredentials;

var keywordQuery = new KeywordQuery(clientContext) { QueryText = "*", RowLimit = 5 };
var graphQuery = new QueryPropertyValue
{
StrVal = "ACTOR(ME, action:1020)",
QueryPropertyValueTypeIndex = 1
};
keywordQuery.Properties.SetQueryPropertyValue("GraphQuery", graphQuery);

var graphRank = new QueryPropertyValue
{
StrVal = @"{""features"":[{""function"":""EdgeTime""}]}", // IntVal, BoolVal, StrArray
QueryPropertyValueTypeIndex = 1 // 1 = string, 2 = int, 3 = bool, 4 = string array
};

keywordQuery.Properties.SetQueryPropertyValue("GraphRankingModel", graphRank);
// Set ranking model as per http://msdn.microsoft.com/en-us/library/office/dn783218(v=office.15).aspx when sorting
// DO NOT SET IF _NOT_ USING: GraphRankingModel
keywordQuery.RankingModelId = "0c77ded8-c3ef-466d-929d-905670ea1d72";

var searchExecutor = new SearchExecutor(clientContext);
ClientResult<ResultTableCollection> results = searchExecutor.ExecuteQuery(keywordQuery);
clientContext.ExecuteQuery();

var separator = new string('-', 60);

foreach (ResultTable resultTable in results.Value)
{
Console.WriteLine("Table: " + resultTable.TableType);
foreach (var row in resultTable.ResultRows)
{
WriteColor(ConsoleColor.Green, "\t" + separator + "\n");
foreach (string key in row.Keys)
{
if (row[key] == null) continue;
string value = row[key].ToString();
int maxLengthToPrint = value.Length > 50 ? 50 : value.Length; //trim output for show yo
WriteColor(ConsoleColor.Yellow, "\t" + key + "\t");
Console.WriteLine(value.Substring(0, maxLengthToPrint));
}
}
}
}
}

private static void WriteColor(ConsoleColor color, string text)
{
ConsoleColor c = Console.ForegroundColor;
Console.ForegroundColor = color;
Console.Write(text);
Console.ForegroundColor = c;
}