in

Dot Net Mafia

Group site for developer blogs dealing with (usually) .NET, SharePoint, Office 365, Mobile Development, and other Microsoft products, as well as some discussion of general programming related concepts.

This Blog

Syndication

Archives

Corey Roth [MVP]

A SharePoint MVP bringing you the latest time saving tips for SharePoint 2013, Office 365 / SharePoint Online and Visual Studio 2013.

How to: Query Search with the SharePoint 2013 Client Object Model

When I first gave the Preview of Search in SharePoint 2013, I mentioned that we could now query search using the Client Object Model.  After enough digging through the documentation, I finally pieced together the steps required to get search results back using this new API.  Today, I will demonstrate how to query from a console application.  To get started, we first need to add referenced to the appropriate assemblies.  These assemblies can be found in the ISAPI folder of the 15 hive.

  • Microsoft.SharePoint.Client.dll
  • Microsoft.SharePoint.Client.Runtime.dll
  • Microsoft.SharePoint.Client.Search.dll

Now in our console application, we need to add the necessary references.

using Microsoft.SharePoint.Client;

using Microsoft.SharePoint.Client.Search;

using Microsoft.SharePoint.Client.Search.Query;

This next step should be familiar if you have used the Client Object Model before in SharePoint 2010.  Start by creating a ClientContext object and pass in the URL to a site.  Put this in a using block.

using (ClientContext clientContext = new ClientContext("http://servername"))

We then need to create a KeywordQuery class to describe the query.  This class is similar to the server side KeywordQuery class but there are some differences.  We pass the ClientContext into the constructor.

KeywordQuery keywordQuery = new KeywordQuery(clientContext);

To set the query use the QueryText property.  In this case, I am doing a search for the keyword “SharePoint”.

keywordQuery.QueryText = "SharePoint";

Unlike the server object model, with the Client OM we have to use another class, SearchExecutor, to send the queries to the search engine.  We pass a ClientContext to it as well:

SearchExecutor searchExecutor = new SearchExecutor(clientContext);

To execute the query, we use the ExecuteQuery method.  It returns a type of ClientResult<ResultTableCollection>

ClientResult<ResultTableCollection> results = searchExecutor.ExecuteQuery(keywordQuery);

However, the query doesn’t actually execute until you call ExecuteQuery() on the ClientContext object.  If you have done a lot of Client OM work before, you might think you need to call Load() first but it is not required.

clientContext.ExecuteQuery();

Assuming no exception occurs, you can now iterate through the results.  The ClientResult<ResultTableCollection> will have a property called Value.  You will want to check the zero index of it to get the search results.  From there, the ResultRows collection has the data of each row.  This object is simply a dictionary object that you can use an indexer with and pass the name of the managed property.  In the example below, I write out the Title, Path, and Modified Date (Write).

foreach (var resultRow in results.Value[0].ResultRows)

{

    Console.WriteLine("{0}: {1} ({2})", resultRow["Title"], resultRow["Path"], resultRow["Write"]);

}

That’s it.  Here is what the entire class looks like together.

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

 

using Microsoft.SharePoint.Client;

using Microsoft.SharePoint.Client.Search;

using Microsoft.SharePoint.Client.Search.Query;

 

namespace SearchClientObjectModelTest

{

    class Program

    {

        static void Main(string[] args)

        {

            using (ClientContext clientContext = new ClientContext("http://sp2010"))

            {

                KeywordQuery keywordQuery = new KeywordQuery(clientContext);

                keywordQuery.QueryText = "SharePoint";

 

                SearchExecutor searchExecutor = new SearchExecutor(clientContext);

 

                ClientResult<ResultTableCollection> results = searchExecutor.ExecuteQuery(keywordQuery);

                clientContext.ExecuteQuery();

 

                foreach (var resultRow in results.Value[0].ResultRows)

                {

                    Console.WriteLine("{0}: {1} ({2})", resultRow["Title"], resultRow["Path"], resultRow["Write"]);

                }

 

                Console.ReadLine();

            }

        }

    }

}

As you can see, you can get started with Search using the Client Object Model with relatively few lines of code.  This certainly beats, constructing that nasty XML file that the Search Web Service takes.

I cross-posted the Visual Studio Solution to code.msdn.microsoft.com.

Follow me on twitter: @coreyroth.

Comments

 

SharePoint 2013 Client Object Model Keyword Search Query « Sladescross's Blog said:

Pingback from  SharePoint 2013 Client Object Model Keyword Search Query &laquo; Sladescross&#039;s Blog

September 11, 2012 4:01 AM
 

Dragan Panjkov said:

What API would you recommend for search scenario using provider-hosted SharePoint app (ASP.NET)? I tried with Managed CSOM, but after deployment to test environment I faced with "Access Denied" errors for ordinary users.

September 26, 2012 12:56 AM
 

CoreyRoth said:

@Dragan the reason for that is likely because CSOM  will use the credentials of the currently signed in user.  You can still use this API, but you will need to provide a set of credentials that has access to search.

September 26, 2012 11:29 AM
 

Guillermo Bas said:

Hi Corey, I'm looking for this simple in JavaScript using the new and improved JSOM for SharePoint 2013. There is no documentation on search api for JSOM anywhere... Could you help me on this?

October 25, 2012 3:58 AM
 

CoreyRoth said:

@Guillermo This sample should help.  It got me started.  code.msdn.microsoft.com/.../SharePoint-2013-Perform-a-1bf3e87d

October 26, 2012 8:05 AM
 

CoreyRoth said:

@Guillermo Unfortunately, there isn't really much documentation on this yet.  That's why I wrote this post.  Hopefully, it helps.

November 7, 2012 10:43 AM
 

OLC said:

A question about the ExportPopularQueries method( in SearchExecutor class). I have excuted the cotnext.ExucteQuery method , but it always returns object with 0 results.And I have tried all kinds of guid(see:www.dotnetmafia.com/.../list-of-common-sharepoint-2013-result-source-ids.aspx).

Any suggestions?

April 8, 2013 8:37 PM
 

CoreyRoth said:

@MB you can look at the TotalRows property on the ResultTable object to get the total row count for use with paging.

November 13, 2013 8:35 AM
 

MB said:

@Corey - thanks.  I found that.  My issue with it is that it changes as I page.  RowLimit = 10, StartRow = X, TotalRows = 200

As I page through it, the TotalRows changes (up/down) with nealy each page....the only value changing is the StartRow...the RowLimit and QueryText stay the same.   Is it a rough query count?

November 14, 2013 11:00 AM
 

CoreyRoth said:

@MB ah yes.  This is a known behavior of search.  The total row count unfortunately is estimated.  You'll notice the same thing as you page through a large result set in the search center.  Not much we can do about that.  It's been like that forever.

November 15, 2013 9:03 AM
 

MB said:

Thanks.  I see that behavior.   Any idea where we can see a list of ResultTypeId's ?  

November 19, 2013 10:09 AM
 

CoreyRoth said:

@MB Unfortunately, there is nothing in the client API to get a list of IDs.  It's a big limitation of the client model when working with search.

November 27, 2013 10:15 AM
 

MB said:

Can you add columns from a list to the search results of the ClientResult result table?  We have a list template with 5 custom columns, crawled and mapped to managedproperties.  the kq.SelectProperties.add(colname) adds the result but does not bring the content of the column with it.

May 2, 2014 12:44 PM
 

K15 said:

Hi Corey !

I used this search for content search for documents, but can you please guide me to people search which can search users from sharepoint site by using csom api just by passing a user's name or some short name.

July 25, 2014 1:33 AM
 

JK said:

To get Search results in provider - hosted app,  i have to set up search   on Sharepoint Site where i use that app?

October 7, 2014 4:07 AM
 

fss said:

thank you for your post.

January 22, 2015 7:53 AM
 

fss said:

thank you for your post.

January 22, 2015 7:53 AM

Leave a Comment

(required)  
(optional)
(required)  
Add

About CoreyRoth

Corey Roth is an independent SharePoint consultant specializing in ECM, Apps, and Search.
2015 dotnetmafia.
Powered by Community Server (Non-Commercial Edition), by Telligent Systems