Programmatically working with Keyword Search Queries in SharePoint 2013


With the improvement of the Search capabilities in SharePoint 2013, its importance in custom solutions has increased. Following are a few tips that can help you work programmatically with Keyword Search Queries in SharePoint 2013.

Search: more important than ever before

One of the great investment areas in SharePoint 2013 is SharePoint 2013 Search. With the new and improved capabilities search is no longer the thing that you only use when you need to find something. SharePoint 2013 Search offers us new scenarios to support productivity and change the way we publish web content.

Changing the game

Although in the previous versions of SharePoint Search was present it wasn’t used as heavily as it is in SharePoint 2013. For the majority of scenarios the scope of a single Site Collection wasn’t a limitation and using CAML query was how we retrieved data.

In SharePoint 2013 using SharePoint 2013 Search and its analytics capabilities we can now not only present static content aggregations to our users but using the information about them we can present them with relevant content, content that they are likely to find helpful.

There is always room for development

With its search engine improved SharePoint 2013 offers us new Web Parts that help us get the right data from the search index. One of such Web Parts is the Content Search Web Part: a rich and highly customizable Web Part that helps us building dynamic content aggregations. And even though its capabilities allow you build rich solutions there are still situations where you need some custom development and have to interact with SharePoint 2013 Search programmatically.

Programmatically working with Keywords Search Queries in SharePoint 2013

The first entry point when working programmatically with Keyword Search Queries in SharePoint 2013 is an instance of the KeywordQuery class. Depending on your requirements there are a few ways in how you can instantiate it, but probably the easiest way, from the testing perspective, is to use the constructor with the SPSite parameter:

using (SPSite site = new SPSite("http://www.mavention.nl.local")) {
    KeywordQuery kq = new KeywordQuery(site);
}

The next step is to specify the query that should be executed. Although you could set it directly on the KeywordQuery object, configuring it in a Result Source instead offers you greater flexibility with regard to query management and configuring query rules and user segments later on. You can set which Result Source the Keyword Query should use using the SourceId property:

using (SPSite site = new SPSite("http://www.mavention.nl.local")) {
    KeywordQuery kq = new KeywordQuery(site);
    kq.SourceId = new Guid("0cc4911f-4f1a-4052-b3e4-72f839e182ce");
}

When building queries in Result Sources you will often use parameters that will allow you to reuse the Result Source across the different parts of your website and retrieve the content as required. Following is a sample query that we use on mavention.nl to retrieve content from catalog located on our authoring site:

{searchTerms?} (contentclass:sts_listitem OR IsDocument:True) SPSiteUrl:https://authoring.mavention.nl.local ListId:84cab1cc-8290-4fa7-86d0-abbb41e82581 {?owstaxidMvItemType:{Tag}}

In the query above we’re using two parameters. First there is the searchTerms parameter where the additional query can be added. Then, at the end, there is the Tag parameter that allows us to retrieve only particular type of pages. This has to do with the fact that we are using one catalog per language with all types of pages stored within.

The searchTerms part of the query can be filled using the QueryText property:

using (SPSite site = new SPSite("http://www.mavention.nl.local")) {
    KeywordQuery kq = new KeywordQuery(site);
    kq.SourceId = new Guid("0cc4911f-4f1a-4052-b3e4-72f839e182ce");
    kq.QueryText = "SlugOWSTEXT:easier-working-size-based-image-renditions-sharepoint-2013";
}

This will make our query look like:

SlugOWSTEXT:easier-working-size-based-image-renditions-sharepoint-2013 (contentclass:sts_listitem OR IsDocument:True) SPSiteUrl:https://authoring.mavention.nl.local ListId:84cab1cc-8290-4fa7-86d0-abbb41e82581

As you can see the query text has been added to the query right where the searchTerms parameter was located and the Tag parameter, as it hasn’t been set, has been removed from the query.

If we wanted to set the value of the Tag parameter we would do so using the Properties property:

using (SPSite site = new SPSite("http://www.mavention.nl.local")) {
    KeywordQuery kq = new KeywordQuery(site);
    kq.SourceId = new Guid("0cc4911f-4f1a-4052-b3e4-72f839e182ce");
    kq.QueryText = "SlugOWSTEXT:easier-working-size-based-image-renditions-sharepoint-2013";
    kq.Properties["Tag"] = "#d94de865-cb39-44cc-92c6-0ed6a344e333";
}

With this our search query will look as follows:

SlugOWSTEXT:easier-working-size-based-image-renditions-sharepoint-2013 (contentclass:sts_listitem OR IsDocument:True) SPSiteUrl:https://authoring.mavention.nl.local ListId:84cab1cc-8290-4fa7-86d0-abbb41e82581 owstaxidMvItemType:#d94de865-cb39-44cc-92c6-0ed6a344e333

Tip: If you want to see how the query template from the Result Source is being transformed by the different parameters configured on the search query look in the ULS log for QueryTemplateHelper.

The last part is to execute the search query to get the search results. This has changed in SharePoint 2013 and works as follows:

using (SPSite site = new SPSite("http://www.mavention.nl.local")) {
    KeywordQuery kq = new KeywordQuery(site);
    kq.SourceId = new Guid("0cc4911f-4f1a-4052-b3e4-72f839e182ce");
    kq.QueryText = "SlugOWSTEXT:easier-working-size-based-image-renditions-sharepoint-2013";
    kq.Properties["Tag"] = "#d94de865-cb39-44cc-92c6-0ed6a344e333";
    ResultTableCollection resultTables = new SearchExecutor().ExecuteQuery(kq);
}

Upon the execution the resultTables object will contain all the result tables returned by SharePoint 2013 Search from which you will have to extract your search results.

Summary

With the increased importance of SharePoint 2013 Search it has become essential to understand how search queries work and how you can interact with them programmatically. Although there are more settings that can be configured on the KeywordQuery object than discussed in this article, it provides you with a solid base that you can use to expand your knowledge of programmatically working with SharePoint 2013 Search queries.

Others found also helpful: