Saturday, November 9, 2013

Problem with missing catalog connections when use customized search result source in Sharepoint 2013

Customized search result sources (Site settings > Search result sources) are one of the ways to customize search results shown in search web parts on your site. It allows to add additional search conditions which will be added to the search keywords entered by user in search textbox. Another way to do it is to change query in Content by search web parts’ properties one by one, but in this case changes will affect only single web part. While if you use customized search result source for site collection, all search web parts will use it by default (it will still possible to override search result source for particular web parts).

When create customized search result source, MS recommends to copy one of existing OTB search result sources and then change its properties:

image

Note that “Local SharePoint Results” source is set as default.

Here is the code which shows how we can copy “Local SharePoint Results” source programmatically to “Local SharePoint Results (customized)” and change its query text:

   1: var searchAppProxy = getSearchServiceApplicationProxy(site);
   2: var federationManager = new FederationManager(searchAppProxy);
   3: var searchOwner = new SearchObjectOwner(SearchObjectLevel.SPSite, site.RootWeb);
   4: var resultSource = federationManager.CreateSource(searchOwner);
   5: resultSource.Name = "Local SharePoint Results (customized)";
   6: resultSource.ProviderId = federationManager.ListProviders()["Local SharePoint Provider"].Id;
   7: resultSource.CreateQueryTransform(new QueryTransformProperties(), query);
   8: resultSource.Commit();
   9: federationManager.UpdateDefaultSource(resultSource.Id, searchOwner);

The method getSearchServiceApplicationProxy(), used in the example above is the following:

   1: private SearchServiceApplicationProxy getSearchServiceApplicationProxy(SPSite site)
   2: {
   3:     var serviceContext = SPServiceContext.GetContext(site);
   4:     if (serviceContext == null)
   5:     {
   6:         throw
   7: new Exception("Can't get search service application proxy: serviceContext is null");
   8:     }
   9:  
  10:     var searchAppProxy =
  11:         serviceContext.GetDefaultProxy(typeof(SearchServiceApplicationProxy))
  12:             as SearchServiceApplicationProxy;
  13:     if (searchAppProxy == null)
  14:     {
  15:         throw
  16: new Exception("Can't get search service application proxy: searchAppProxy is null");
  17:     }
  18:     return searchAppProxy;
  19: }

Note line 9 from the first example above where we call federationManager.UpdateDefaultSource() method. It sets customized search result source as default, which means all search web parts on the site will use it by default. After this search result sources will look like this in our site collection:

image

Everything is fine and our search web parts started to use new customized search result source. The problems begin when we will try to connect to catalog for using cross site publishing on our site collection.

Let’s assume that we have another site collection with News sub site and we want to publish Pages doclib on this sub site as catalog so content from this doclib will be available on other site collections and web applications. After we published it as catalog and made full crawl of the site which contains this doclib, appropriate catalog connection should appear in Site settings > Manage catalog connections on other site collections. However if we will go in this page on our site collection with customized default result source, there won’t be any connection available:

image

I.e. there are no catalog connections visible at all (if you have several sources published as catalog, no one will be shown). What is the problem?

First of all if you will create new OTB site collection and check catalog connections from there, you will find them:

image

So my hypothesis was that catalog connections disappear when we copy OTB result source to customized. But as it turned out the reason is not exactly in the copying. Catalog connections disappear when we set customized result source as default. They disappear not only from UI, it is also not possible to get them programmatically after that. The following code which gets catalog connection settings by name will return null:

   1: private CatalogConnectionSettings getCatalogByName(SPSite site, string catalogName)
   2: {
   3:     int num;
   4:     var catalogs = PublishingCatalogUtility.GetPublishingCatalogs(site, 0, 10,
   5:         string.Empty, out num);
   6:     if (catalogs == null)
   7:     {
   8:         return null;
   9:     }
  10:     foreach (var c in catalogs)
  11:     {
  12:         if (c.CatalogName == catalogName)
  13:         {
  14:             return c;
  15:         }
  16:     }
  17:     return null;
  18: }
 
How to avoid this problem? Well solution is quite simple: before to connect to catalog mark OTB “Local SharePoint Results” source as default:
image
After this catalog connections will appear in Site settings > Manage catalog connections and you will be able to connect to them (they may appear after couple of seconds, not immediately). Connect and then set customized “Local SharePoint Results (customized)” source back as default. As result you will have working catalog connection and customized search result source. Hope that this information will help you.

No comments:

Post a Comment