How to: Use the SharePoint 2013 Search KeywordQuery Class

Posted Thursday, January 3, 2013 11:42 AM by CoreyRoth

Over the past few versions of SharePoint, I have provided a number of blog posts on how to query search.  Of those, my posts on how to use the KeywordQuery class using KQL are some of the most popular (2010 and 2007).  In continuing that tradition, I am proud to present the “How to” post on using the KeywordQuery class in SharePoint 2013.  The good news: your old KeywordQuery code should still work.  The bad news: the way you did it is marked completely obsolete.  I actually had to dig through quite a bit of documentation to find the right API that wasn’t obsolete.  One thing that always provided confusion was that there were similar classes named KeywordQuery in both Microsoft.Search.Query and Microsoft.Office.Server.Search.Query.  To reduce some of that confusion, the KeywordQuery class in Microsoft.Search.Query is now marked as obsolete.  The new updated class is in Microsoft.Office.Search.Query.  Microsoft may have killed the word Office from the name of the product in 2010, but it’s alive and well in the API.

Now let’s talk about what we need to execute some queries with our code.  The code here today will work well from farm solutions in SharePoint as well as other .NET applications hosted on the same SharePoint server.  We’ll be building a console application today.  If you want to query remotely using the object model, then you will need to use the Search Client Object Model which I covered previously.  Create a new console application, and then you will need to add a few references.  These can be found in the 15 hive in the ISAPI folder.  Add the following:

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

The classes we need are in the search assembly but you’ll get lots of errors about dependencies missing if you don’t include the others.  We then need the following references.  This gives us what we need for search, SharePoint, and for the underlying datatable object that is available after we query.

using System.Data;

using Microsoft.SharePoint;

using Microsoft.Office.Server.Search.Query;

Once we have this, we’re ready to get started.  There are many ways to instantiate a KeywordQuery object.  For simplicity, I am just going to pass a SPSite object for one of my site collections.  You can also pass a SPWeb or you can use the proxy technique like I used in my SharePoint 2010 post.  We’ll first, get our SPSite object.

using (SPSite siteCollection = new SPSite("http://server/sitecollection"))

We then create a KeywordQuery object using that site collection.

KeywordQuery keywordQuery = new KeywordQuery(siteCollection);

Now, we specify our query using the QueryText field.  This is where you can use your custom KQL queries.  The documentation team updated the post on this so there are a lot of good tips here.  I am just going to search for the word SharePoint.

keywordQuery.QueryText = "SharePoint";

In the past, we would then set the ResultsProvider and ResultTypes that we want, but now we don’t have to.  In fact, this whole process takes considerably less code.  Instead we use the new SearchExecutor class that I first mentioned in my Client OM post.

SearchExecutor searchExecutor = new SearchExecutor();

We then use it’s ExecuteQuery method passing it our KeywordQuery class.

ResultTableCollection resultTableCollection = searchExecutor.ExecuteQuery(keywordQuery);

Assuming it executes correctly, we can then get our search results.  Before, we used to use an indexer using ResultTypes.ReleventResults to get the table of results we need.  The indexer has been made obsolete, so now we must use the new Filter method.  I figured out what it required from the obsolete descriptor of the indexer.  For the first value, it needs a string with a value of TableType and since the previous enum is also obsolete, we now use KnownTableTypes.RelevantResults.

var resultTables = resultTableCollection.Filter("TableType", KnownTableTypes.RelevantResults);

It returns an IEnumerable<ResultType>, so we need to filter it.  I just FirstOrDefault() to get the table we need.

var resultTable = resultTables.FirstOrDefault();

Previously, we then had to load the data into a DataTable which took a few more lines of code.  However, now that is not required due to the new Table property.

DataTable dataTable = resultTable.Table;

Now that you have a DataTable, you can bind it or query it as you see.  You can also look at the results using the visualizer in Visual Studio.

KeywordQueryDataSetVisualizer

Here is the entire code snippet.

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

 

using System.Data;

using Microsoft.SharePoint;

using Microsoft.Office.Server.Search.Query;

 

namespace SearchConsoleApplication1

{

    class Program

    {

        static void Main(string[] args)

        {

            using (SPSite siteCollection = new SPSite("http://server/sitecollection"))

            {

                KeywordQuery keywordQuery = new KeywordQuery(siteCollection);

                keywordQuery.QueryText = "SharePoint";

 

                SearchExecutor searchExecutor = new SearchExecutor();

                ResultTableCollection resultTableCollection = searchExecutor.ExecuteQuery(keywordQuery);

                var resultTables = resultTableCollection.Filter("TableType", KnownTableTypes.RelevantResults);

 

                var resultTable = resultTables.FirstOrDefault();

 

                DataTable dataTable = resultTable.Table;

            }

        }

    }

}

So if you have a lot of search based code, you may need to do some updates at some point.  However, I think these are good changes and simplify the process a little bit.  In an upcoming post, I’ll cover some of the new things you can do with the KeywordQuery class.

Comments

# How to: Use the SharePoint 2013 Search KeywordQuery Class &#8230; | Mastering Sharepoint

Pingback from  How to: Use the SharePoint 2013 Search KeywordQuery Class &#8230; | Mastering Sharepoint

# SharePoint 2013 Search with Keyword Query Compatibility &laquo; Sladescross&#039;s Blog

Pingback from  SharePoint 2013 Search with Keyword Query Compatibility &laquo; Sladescross&#039;s Blog

# My SharePoint links January 5, 2013 | Jeremy Thake&#039;s musingsJeremy Thake&#039;s musings

Pingback from  My SharePoint links January 5, 2013 | Jeremy Thake&#039;s musingsJeremy Thake&#039;s musings

# re: How to: Use the SharePoint 2013 Search KeywordQuery Class

Tuesday, January 15, 2013 4:52 AM by roelBSS

Hi Corey,

Thanks yet again for a great write-up on SharePoint 2013. I am a bit confused however, about the proper class to use in this case. You state two different namespaces in the text, but in the code, you use Microsoft.Office.Server.Search.Query, which is probably the correct one, right?

I have implemented your example, and have a question  about the "QueryInfo" object that is filled after you issue a query: The TotalResults property stays 0, even though you have lots of results in the results table. Have you notices this before? Do you know of a workaround or solution to the problem? All other properties of the QueryInfo are being updated after querying, just not TotalResults.... And this is a property you'd really like to know in a search based application ;)

Thanks in advance,

Regards,

RoelBSS

# re: How to: Use the SharePoint 2013 Search KeywordQuery Class

Wednesday, February 6, 2013 9:31 AM by CoreyRoth

@RoelBSS thanks for point out the issue with the namespace.  I have corrected it.

As for the QueryInfo object, I haven't noticed that.  I'll try and take a look when I have a chance.

# SharePoint Daily &raquo; Blog Archive &raquo; SharePoint 2013 Crystal Ball; Ways to Have Conversations in SharePoint 2013; Windows Phone 8 is a Good Choice

Pingback from  SharePoint Daily  &raquo; Blog Archive   &raquo; SharePoint 2013 Crystal Ball; Ways to Have Conversations in SharePoint 2013; Windows Phone 8 is a Good Choice

# SharePoint 2013 Crystal Ball; Ways to Have Conversations in SharePoint 2013; Windows Phone 8 is a Good Choice

Tuesday, February 12, 2013 7:51 AM by SharePoint Daily

Happy Mardi Gras. The first round of Hurricanes is on me. - Dooley Top News Stories 2013 Crystal Ball

# re: How to: Use the SharePoint 2013 Search KeywordQuery Class

Wednesday, February 27, 2013 1:28 AM by Satya

Hi,

Nice post.. I want to use keyword query class to search in People index, how can i achieve that.

# re: How to: Use the SharePoint 2013 Search KeywordQuery Class

Thursday, April 11, 2013 10:19 PM by CoreyRoth

@Satya Use the Result Source for Local People Results.  www.dotnetmafia.com/.../list-of-common-sharepoint-2013-result-source-ids.aspx

# re: How to: Use the SharePoint 2013 Search KeywordQuery Class

Friday, April 26, 2013 1:50 AM by Mark

Hi, have you tried to use special scope in KeywordQuery?  In sp2013 we have result sources, I want to define search scope.

# re: How to: Use the SharePoint 2013 Search KeywordQuery Class

Tuesday, November 12, 2013 10:03 AM by MB

This example throws a missible Microsoft.SharePoint.Client.ServerRuntime error.  Am I missing an unmentioned DLL or install?

# Consultas con el modelo de objetos de servidor de SharePoint 2013 | materiagris.net

Pingback from  Consultas con el modelo de objetos de servidor de SharePoint 2013 | materiagris.net

# re: How to: Use the SharePoint 2013 Search KeywordQuery Class

Thursday, May 22, 2014 7:03 AM by marcos

Hi Corey,

Thanks for the very helpful write up.

I was wondering if it is possible to search without a keyword.Eg.: Is it possible to simply list out all MS word documents using this keywordquery class?

# re: How to: Use the SharePoint 2013 Search KeywordQuery Class

Tuesday, May 27, 2014 9:56 AM by CoreyRoth

@Marcos sure you can do that with the FileExtension keyword.  Just enter a query such as FileExtension:docx and it will return all Word documents.

# re: How to: Use the SharePoint 2013 Search KeywordQuery Class

Monday, June 30, 2014 12:35 PM by Mostafa

This code doesn't return any results even though i have used SP2013 Query tool to test out my query which has one keyword and it returns 1 result while using code doesn't return results. any idea why would this happen ?

# re: How to: Use the SharePoint 2013 Search KeywordQuery Class

Wednesday, March 18, 2015 6:52 AM by Chil

I am trying to use the following query for a customized keyword search webpart.

Created:{Today-365} and IsDocument:1

Once I use the above query on “Build your Query” at SC level, I got some search results.

But, Once I use String queryText = "Created:{Today-365}"; inside of my keyword query console program. (my keyword search console program works fine with other keyword query)

I got the error” we did not understand your search term”.

Could you explain to me why and any solution?

# re: How to: Use the SharePoint 2013 Search KeywordQuery Class

Wednesday, July 1, 2015 10:12 AM by Sushrut

I am using keyword query to get community sites using querytext as "WebTemplate:Community Path:/Communities/" where communities is the site collection URL.

If I use the same query in content by search web part, I get all the result and which is higher than number I get when I execute query programatically. I am using same account to see the results so it should not be related to permissions. Also I have site collection admin permission.

Is there anything I am mising?

# re: How to: Use the SharePoint 2013 Search KeywordQuery Class

Thursday, July 9, 2015 10:45 AM by CoreyRoth

@Sushrut my guess is that you are querying a different result source when using the API.  Make sure you specify the same result source and don't just assume it's the same.

# Links utiles Search Sharepoint | Viejo Programmer

Thursday, September 24, 2015 10:33 AM by Links utiles Search Sharepoint | Viejo Programmer

Pingback from  Links utiles Search Sharepoint | Viejo Programmer

# SharePoint 2013 Crystal Ball; Ways to Have Conversations in SharePoint 2013; Windows Phone 8 is a Good Choice &#8211; Bamboo Solutions

Pingback from  SharePoint 2013 Crystal Ball; Ways to Have Conversations in SharePoint 2013; Windows Phone 8 is a Good Choice &#8211; Bamboo Solutions

# re: How to: Use the SharePoint 2013 Search KeywordQuery Class

Friday, October 14, 2016 3:21 AM by Sagar

Hi,

How can I do the same on a user context. I can see that there is a property keywordQuery.PersonalizationData which can get me the same. But I am not sure how to use that. Can someone guide me?

# re: How to: Use the SharePoint 2013 Search KeywordQuery Class

Sunday, January 8, 2017 12:00 PM by Swati

Hi Corey,

Even though, you set a site collection level, such as http://spportal/site/custSite(subsite) the result returns from entire web application which matches the QueryText. Any idea how to return result only from specific site collection I mentioned in the scope such as

using(SPSite custosite =  SPSite("http://spportal/site/custSite")

{

}  

It returns from several other sites such as custSite2, xxSite under SPPortal. Please assist tuning query to return result only from specific subsite.

# re: How to: Use the SharePoint 2013 Search KeywordQuery Class

Wednesday, May 17, 2017 4:40 AM by Samadhan

Hi,

I am using private site on sharepoint, and I want search result from my private site, I am giving comlete url of my site in clientcontext.

When I try to search, it searches in public sites and gives me the result.

How can I get result from my private site?

Regards,

Samadhan

Leave a Comment

(required)
(required)
(optional)
(required)