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.

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.

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.

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.

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.

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.

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.

@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.

@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.

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?

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:

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.

@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.