in

Dot Net Mafia

Group site for developer blogs dealing with (usually) .NET, SharePoint 2013, SharePoint 2010, Office 365, SharePoint Online, 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: Use the SharePoint 2010 Enterprise Search KeywordQuery Class

By now, I’m sure you know that there have been a ton of changes and improvements in SharePoint 2010 Enterprise Search.  The underlying architecture of Enterprise Search has been ripped out of the old SSP model and is now based on Service Applications.  Although, Microsoft abstracted a lot of this away for us so that our old code still works, it’s worth noting and being aware of the changes.  When it came to querying search programmatically in SharePoint 2007, we had a choice of using the API, Web Services, or using the RSS feed.  When using the search API, we typically used the KeywordQuery or FullTextSqlQuery classes.  To this day, those two posts are still in the top 20 on DotNetMafia.com.  This tells me that people must be pretty interested in querying search using their own code.

Today I am going to talk about the KeywordQuery class in SharePoint 2010.  Your code from 2007 will still probably work, but I thought I would tell you about some of the changes.  This also sets the ground for a series of future posts that are coming about querying Enterprise Search.  We’ll talk about the federated query model using the QueryManager class as well as how to use FQL to do advanced queries in FAST.  Today though, we’ll stick to the KeywordQuery class.

In SharePoint 2007, we often got a reference to the KeywordQuery class by passing the URL of a site collection to the constructor.  We can still do that, however, I think the new best practice will be to pass a reference to the SearchServiceApplicationProxy.  The trick of course is getting that reference.  First, you need to determine the name of your Search Service Application.  For a typical Enterprise Search installation it is called Search Service Application.  However, it can be called anything depending on how you configured SharePoint.  For FAST, it might be called something like FAST Content SSA.  Go to Central Administration –> Service Applications and take a look.

SearchServiceApplicationAndProxy

The proxy will usually have the same name as the Service Application, so in my case here the name of my proxy is Search Service Application.  Now we just can’t get a reference to the SearchServiceApplicationProxy directly.  We have to go through the SearchQueryAndSiteSettingsServiceProxy class first.  According to the SDK, the function of going through this service is to ensure queries are load balanced.  Here is how you get a reference to the query and settings proxy.  It also assumes this code is executing on one of the servers in the farm.

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

Now that we have a reference to the settings proxy, we can get a reference to the SearchServiceApplicationProxy with the name of the proxy that we saw above.  Change the name to match whatever yours is called.

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

Now you can pass this proxy to the constructor of the KeywordQuery.

KeywordQuery keywordQuery = new KeywordQuery(searchProxy);

The rest is pretty much the same.  There is one new parameter that you may want to consider setting when you have multiple search providers (i.e.: FAST for documents and SharePoint Enterprise Search for People).  This parameter is ResultsProvider.  It’s an enum with a value of Default, FASTSearch, and SharePointSearch.  However, I believe you can use this to switch between FAST and SharePoint Search when you don’t specify the SearchServiceApplicationProxy (i.e.: you used the site collection URL).  So for example when you had FAST installed, if you wanted to query People, you might set it to SharePointSearch.  The examples I have seen so far leave this to default.   Here is what the rest looks like.

keywordQuery.QueryText = "accounting";

keywordQuery.ResultsProvider = SearchProvider.Default;

keywordQuery.ResultTypes = ResultType.RelevantResults;

ResultTableCollection resultsTableCollection = keywordQuery.Execute();

 

ResultTable searchResultsTable = resultsTableCollection[ResultType.RelevantResults];

DataTable resultsDataTable = new DataTable();

resultsDataTable.TableName = "Results";

resultsDataTable.Load(searchResultsTable, LoadOption.OverwriteChanges);

I can then use the data visualizer to see my results.  There are a few new managed properties that you get by default in the search results.  I’ll talk about these more when we look at using the QueryManager in an upcoming post.

EnterpriseSearchKeywordQueryDataVisualizer

There are a lot of new properties on the KeywordQuery class and I have only begun to explore them, but here are some of the ones I’ve looked at so far.  The first is EnableFQL.  This allows you to submit queries using FAST Query Language.  That’s a whole series of posts by itself.  Just know that you can submit FQL queries using the KeywordQuery class.  Two other interesting properties are EnableNicknames and EnablePhonetic.  This allows you to turn off the cool people search features that are so great at finding peoples names phonetically.  I’ll talk about more options with the KeywordQuery class in the future.  Anyhow, I hope this gets you started using it in SharePoint 2010.

Comments

 

Twitter Trackbacks for How to: Use the SharePoint 2010 Enterprise Search KeywordQuery Class - Corey Roth - DotNetMafia.com - Tip of the Day [dotnetmafia.com] on Topsy.com said:

Pingback from  Twitter Trackbacks for                 How to: Use the SharePoint 2010 Enterprise Search KeywordQuery Class - Corey Roth - DotNetMafia.com - Tip of the Day         [dotnetmafia.com]        on Topsy.com

August 13, 2010 11:08 AM
 

Vishnu Ramkumar said:

Hi...

I followed the code given in the article and tested it in my SPS 2010 environment.

The line

ResultTableCollection resultsTableCollection = keywordQuery.Execute(); is throwing me an exeption saying "No address available for this application.". what could be the reason...?

...Vishnu

September 15, 2010 7:08 AM
 

CoreyRoth said:

@Vishnu Hard to say.  Verify that the search service application name is correct.  Also verify that you can execute queries using the search center as well.

September 22, 2010 12:15 PM
 

TheGenius said:

How to get the best bet result using SPS2010 & keywordQuery?

December 8, 2010 7:55 AM
 

CoreyRoth said:

@TheGenius set the ResultTypes property on the KeywordQuery class to ResultType.SpecialTermResults to return Best Bets.

December 8, 2010 9:04 AM
 

Search Programmatically Call « Sladescross's Blog said:

Pingback from  Search Programmatically Call &laquo; Sladescross&#039;s Blog

January 26, 2011 2:19 PM
 

TheGenius said:

CoreyRoth:

I did what you say but not able to retrieve the result in case of fast search.

Do we need to do anything extra for fast search?

February 1, 2011 10:55 PM
 

CoreyRoth said:

@TheGenius Make sure that you have the name of your FAST Search Query application correct when you set up the SearchProxy.

February 4, 2011 10:33 AM
 

TheGenius said:

CoreyRoth:

Its correct when i give it chance it returns blank tables for the best bets and the visual best bet.

Can you provide me sample code which work in case of FAST search?

So, i Can try the same on my end.

Thnaks for your support.

February 8, 2011 1:29 AM
 

Rocky said:

Hii corey,

I wanted to know how to access the custom refiners using the keywordQyery class

I am doing like this

KeywordQuery keywordQuery = new KeywordQuery(searchProxy);

keywordQuery .refiners="managed property1,managedproperty2";//i have even tried like keywordQuery .Refiners="managedProperty1"

It is not returning any results.

Can you please help regarding this.

Thanks..

March 21, 2011 4:24 AM
 

Karuna Kumar K said:

Hi Corey,

I wrote a web service and written custom search as you mentioned above. I hosted this web service on IIS7 where my sharepoint2010 is also hosted.

But I am not getting the results when i use.

ResultTableCollection resultsTableCollection = keywordQuery.Execute(); This is happening when i host on webserver.(IIS),

If i write the same code in windows or any console application, I am getting the results.

I have chacked all the sttings in IIS but no use.

Couls you please help me?

Thanks in Adbvance.

April 11, 2011 6:27 AM
 

CoreyRoth said:

@Karuna Most likely your results are getting security trimmed.  It's going to call the search API using the account that your application pool has.  If that account does not have access to SharePoint, it won't have any results.  Try changing your application pool account to an account with the appropriate access.

April 12, 2011 2:33 PM
 

CoreyRoth said:

@Rocky Let me look into that.

April 12, 2011 2:33 PM
 

@Learner said:

Hi Corey,

When i try to use the command:

KeywordQuery keywordQuery = new KeywordQuery(searchProxy);

i am getting an error at searchProxy saying something about  overloaded method ..

i am newbie , cant make it out what the error says

can u please help me..

June 17, 2011 5:24 AM
 

CoreyRoth said:

@Leamer What is the exacty error?  Make sure that you have the name matched up exactly to the name of your Search Service Application.

June 20, 2011 4:03 PM
 

Santa said:

Hi Corey,

    I am using KeyWordQuery class for retrieving results from FS4SP.

But while searching for chinese characters it doesn't return any results if I don't set the culture.

<<keywordQuery.Culture = new CultureInfo("zh-cn");">>

Is thare any way the class auto detect the query texts language and returns results.

September 5, 2011 8:00 AM
 

CoreyRoth said:

@Santa not that i know of.  Thanks for the code snippet as it may prove useful to others who are querying using other cultures.

September 6, 2011 11:01 AM
 

Alok said:

Hi Corey,

I want to get search results from one webApplication only.

I've put multiple webApplication names while creating my seach Service. I don't want to create Search Service for each Web Application.

Is there anything i can do with keywordQuery .refiners? How?

Thanks

September 8, 2011 6:33 AM
 

CoreyRoth said:

@Alok There are a couple of ways to handle this.  First, you can create scopes that limit the results to each web application and then just query by scope.  You can also use the Site keyword to limit results under a particular URL.  This post has some examples of that.

www.dotnetmafia.com/.../some-handy-keywords-you-might-find-useful-in-sharepoint-enterprise-search.aspx

September 9, 2011 10:01 AM
 

Dragan Panjkov said:

If I'm using this approach for referencing SearchServiceApplicationProxy, how are the credentials of the current user/user that is performing search saved? Can I expect that, if I don't use SiteCollection first, my search results will depend on my access rights to specific sites/libraries?

June 7, 2012 6:23 AM
 

CoreyRoth said:

@Dragan The KeywordQuery class uses the credentials of the current user.  The documents you see will be security trimmed down to the specific user.

June 7, 2012 12:57 PM
 

Dragan Panjkov said:

@CoreyRoth Thanks.

June 8, 2012 2:35 AM
 

Manas said:

Can any one tell me thw exact process of this configuration?? ie. how can I send an FQL to the FAST

using an ASP.NET web application.

I was trying to use the http://<webserver>/_vti_bin/search.asmx web service. But its wsdl file is not opening from the port.

So any other way to communicate with the FAST Server.

Thanx

September 7, 2012 10:20 AM
 

CoreyRoth said:

You can use the web service with FAST as well.  Be sure you are using the URL from the SharePoint server which hosts the service application and not the FAST server.  To use FQL, you will have to specify a query type of FQL.

September 7, 2012 11:09 AM
 

Manas said:

Thanx CoreyRoth for the reply.

But as I have mentioned that I am not able to open the wsdl file of the web service.  I have tried the  process from the below link    "msdn.microsoft.com/.../gg588339.aspx"    

So when I am trying to add the web reference in my asp.net solution it shows some error. I know how to use the FQL , but the issue is the configuration in the sharepoint so that my asp.net solution can communicate with the FAST via sharepoint.

Thanx

September 10, 2012 12:50 AM
 

CoreyRoth said:

@Manas if you need to call search from a remote application, you'll have to go through the web service.  You probably need to look into the error you are receiving more.

September 10, 2012 8:33 AM
 

Marcel B said:

Hi Corey,

Just to clarify, if I am using Silverlight and if I want to use the Search API, I am still forced to use the web service right? I cannot use the KeywordQuery class nor the FullTextSQLQuery class.

September 19, 2012 12:11 PM
 

kesavan said:

Hi CoreyRoth,

I need to find similar results for my returned result set(FS4SP).

So im trying to get similar results using the docvector managed property and the similarTo property of keywordQuery class.

link:(find similar)

msdn.microsoft.com/.../ff521597.aspx

 var names = from DataRow row in dt.Rows

                                   select (string)row["Docvector"];

                       string[] arr = names.ToArray();

                          keywordQuery.SimilarTo = arr[0];

                        how will i build the query here..  keywordQuery.QueryText = "Query"

here i got my docvector values in a string array.But i dont really know to proceed further.

How do i construct the Query using these docvector values.Can u please refer the link and please help me regarding this.

October 3, 2012 3:52 AM
 

cho said:

What if there is only a search service application proxy (the query SSA lives on a different farm)? Do you need to use the SSA's name, or the remote query SSA's name?

October 4, 2012 2:34 PM
 

CoreyRoth said:

@Marcel That is correct.  Web Service is really your only option.  That story changes in 2013 though.

October 19, 2012 3:28 PM
 

CoreyRoth said:

@Cho specifying the name of the proxy should work although I have never tried that scenario.

October 19, 2012 3:32 PM
 

Nick said:

Hi Corey,

Would you know if there is any limitation to the StartRow property of the KeywordQuery class?

When my StartRow = 100,000, I get the following exception "The search request was unable to execute on FAST Search Server".

I have RowLimit = 500 and start with StartRow = 0. If there are more than 500 results, increment StartRow and execute another query. It seems that I am not able to get more than 100,000 results from FAST.

ResultTableCollection rtable = query.Execute();

ResultTable relevantResultsTable = rtable[ResultType.RelevantResults];

// Load the first 500 items in the  datatable                                              

table.Load(relevantResultsTable, LoadOption.OverwriteChanges);

// While there are more than 500 results, run another query and change the StartRow of the query

while (relevantResultsTable.TotalRows > table.Rows.Count)

{

                       query.StartRow = table.Rows.Count;

                       rtable = query.Execute();

                       relevantResultsTable = rtable[ResultType.RelevantResults];

                       table.Load(relevantResultsTable, LoadOption.PreserveChanges);

}

December 11, 2012 2:23 PM
 

SharePoint 2013 Search with Keyword Query Compatibility « Sladescross's Blog said:

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

January 4, 2013 9:23 AM
 

CoreyRoth said:

@Nick I've heard others report similar issues but I haven't tried it myself.  There may be a limitation here.

February 6, 2013 9:43 AM
 

AG said:

Hi

Anybody can help me , How to read Authoring site List Value from Publish site through code in sharepoint 2013

May 2, 2013 6:07 AM
 

R??f??rences pour D??veloppement en SharePoint | BLOC NOTE POUR D??VELOPPEURS SHAREPOINT said:

Pingback from  R??f??rences pour D??veloppement en SharePoint  | BLOC NOTE POUR D??VELOPPEURS SHAREPOINT

July 8, 2013 1:58 PM
 

Ramakanth said:

We are using FAST and we also encountered this issue and it consistently fails for start row greater than 100000

August 8, 2013 7:11 PM

Leave a Comment

(required)  
(optional)
(required)  
Add

About CoreyRoth

Corey Roth is an Applications Architect at Infusion specializing in ECM and Search.
2012 dotnetmafia.
Powered by Community Server (Non-Commercial Edition), by Telligent Systems