May 2013 - Posts

Result Sources in SharePoint 2013 are quite powerful.  However to make use of them in your queries, you have to know the Id which you pass to the SourceId parameter of a query.  For out-of-the-box result sources, the Ids are static.  When you start creating your own though, you need a way to retrieve the Ids programmatically.  Unfortunately, the only way to retrieve the Ids is to use the managed API.  This means they can’t be retrieved using JavaScript or REST.  With that aside, I still wanted to show you how you could write managed code to retrieve a result source id.

For today’s example, I am going to build a console application, but you could also implement this in a web part or other code directly executing on a SharePoint server in the farm.  Whenever you build a console application using SharePoint, be sure and change the platform target to x64.  Then, we need to add a few references which we can find in the ISAPI folder of the 15 hive.  Add the following assemblies to your project.

  • Microsoft.Office.Server
  • Microsoft.Office.Server.Search
  • Microsoft.SharePoint
  • Microsoft.SharePoint.Security

In our code, we’ll need a heap of assemblies to get started.  Add the following using statements.

using Microsoft.SharePoint;

using Microsoft.SharePoint.Administration;

using Microsoft.Office.Server.Search;

using Microsoft.Office.Server.Search.Administration;

using Microsoft.Office.Server.Search.Administration.Query;

Next, we need to get a reference to the Search Service Application Proxy so that we can retrieve the result source.  There are a number of ways to do this, but I am going to get it by name.

SearchQueryAndSiteSettingsServiceProxy settingsProxy = SPFarm.Local.ServiceProxies.GetValue<SearchQueryAndSiteSettingsServiceProxy>();

SearchServiceApplicationProxy searchProxy = settingsProxy.ApplicationProxies.GetValue<SearchServiceApplicationProxy>("Search Service Application");

Once you have a proxy object, it is easy to get the result source and then the id.  The proxy object has a method GetResultSourceByName method.  You can pass it the name of the result source you want, but you also need to specify a SearchObjectOwner object  to specify which level you want to access it at (Service Application, Site Collection, or Site).  I’ll show you each one starting with Service Application.  In my example, I have result resources created at each level.

ResultSources

This creates a SearchObjectOwner for the site collection.

SearchObjectOwner serviceApplicationOwner = new SearchObjectOwner(SearchObjectLevel.Ssa);

Next we pass it as the second parameter to GetResultSourceByName.  The first parameter is simply the name of the result source.

SourceRecord serviceApplicationResultSource = searchProxy.GetResultSourceByName("Service Application Result Source", serviceApplicationOwner);

Assuming, there is a matching result source, all you need to do is use the Id parameter on the SourceRecord object.

Guid serviceApplicationResultSourceId = serviceApplicationResultSource.Id;

You can then use that Id in your own queries using the SourceId keyword.

If you want to reference a result source at the site collection or site level, you need to do a few extra steps.  Start by getting a web object.  You need this whether you are using a site collection or site and I’ll show you why shortly.

using (SPSite site = new SPSite("http://sp2010/sites/test"))

{

    using (SPWeb web = site.OpenWeb())

    {

 

    }

}

Inside our using block, we’ll add our code.  Let’s get things at the site (web) level first.  We do this by creating a SearchObjectOwner specifying a SearchObjectLevel of SPWeb and passing a second parameter containing our SPWeb object.

SearchObjectOwner siteOwner = new SearchObjectOwner(SearchObjectLevel.SPWeb, web);

Now, we pass the SearchObjectOwner to the GetResultSourceByName method like before.

SourceRecord siteResultSource = searchProxy.GetResultSourceByName("Site Result Source", siteOwner);

Like before, we can use the Id parameter to get the id of the result source.

To access result sources at a site collection, the API is a bit different than what you might be used to.  We create a new SearchObjectOwner object and we specify a SearchObjectLevel of SPSite.  In this case, we also pass it the SPWeb object from before even though we want the site collection.  It’s a bit different but it works.  Here’s what it looks like.

SearchObjectOwner siteCollectionOwner = new SearchObjectOwner(SearchObjectLevel.SPSite, web);

SourceRecord siteCollectionResultSource = searchProxy.GetResultSourceByName("Site Collection Result Source", siteCollectionOwner);

That’s all it takes to get a result source id.  As I mentioned earlier, it is unfortunate that we can’t get a result source id any other way, but this will work if you are writing managed code in on-premises SharePoint 2013.

I’ve had yet another fun week up here in Canada.  I gave a brand new talk about the new ways to query search in SharePoint 2013.  I had a room full of developers that asked a lot of great questions.  As promised, my slide deck is below at SlideShare.

Five ways to query SharePoint 2013 Search

In the session, I mentioned that I had code samples on MSDN Code, so I am providing the link below.  Try them out and download them and rate them if you find them useful.

SharePoint 2013 Search Samples

Follow me on twitter: @coreyroth