in

Dot Net Mafia

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

This Blog

Syndication

Corey Roth [MVP]

A SharePoint MVP bringing you the latest time saving tips for SharePoint 2010, Office 365, SharePoint Online, MOSS 2007, ASP.NET, LINQ, and Visual Studio 2010

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

Leave a Comment

(required)  
(optional)
(required)  
Add

About CoreyRoth

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