On a few projects recently there has been a need to use the search API. You may wonder why you would think to use the search API at all considering we have all the aggregation we need with the Content Query Web Part. I hear you and yes I understand however there are occasions when you will need to use this. The CQWP is great but does have a few problems when you reach over the 2000 lists in a site collection limit, even though you can set the limit using the "<Lists />" parameter to unlimited it still tends to fail. A quick way of resolving this is to use the search API, not only is very easy and quick to use, but it also allows for cross site collection searches out of the box.
So in this post I am going to show you the basics of using the search API. So to begin with I am not going to build a web part or control, I am simply going to build a windows application that just returns to rudimentary data from the search we perform.
Firstly I have created a form that looks like this:
The form is fairly straight forward and not sexy in anyway. It has a textbox for the portal URL, a few boxes for the actual search query and then the results. Of course there is a button to run this query also. So let's begin with the code. The first thing to note here is that you need to add the following references:
We then need to connect to the site we want to use. Below is the standard statement I would use, notice this is coming from the textbox field on the form.
Once we have our connection to the site we then combine the various textbox values to create the full SQL Query.
We then need to tell the code to run a "FullTextSQLQuery", notice I have enabled "Stemming", "Trimming of Duplicates" and made sure the results are "RelevantResults".
Now we have our query created and out base settings for the "FullTextSQLQuery" we need to actually execute this and populate the "ResultTable"
After the "ResultTable" is populated a dataset is populated with these values, this just makes it easier for my example here.
Now I am going to create a "StringBuilder" so I can separate the type field values and then format these so my results are dynamic based on the fields type in the query. If I did not do this I would have needed to rely on typing each field that was selected out for the results to work.
Lastly we populate the textbox with the results. So let's see what it looks like:
I am using a basic query as shown above:
"SELECT Title, URL FROM Scope () WHERE FREETEXT(DEFAULTPROPERTIES, 'Administrator') ORDER BY RANK"
The results for this are as follows, excuse the formatting here.
So what if we wanted to run a similar query that returned users "My Sites" instead. Let's modify the query again:
"SELECT Title, URL FROM Scope() WHERE "scope"= 'People' AND FREETEXT(DEFAULTPROPERTIES, 'Administrator') ORDER BY RANK"
The returns just the administrators my site link, if we take off the end part of the query we get the entire "My Site" site links.
"SELECT Title, URL FROM Scope () WHERE "scope"= 'People'"
Now what about if we wanted to get only pages based on a specific content type? The query needs to be modified as shown below:
"SELECT Title, URL FROM Scope() WHERE ContentType = 'Article Page' ORDER BY RANK"
Or you could search for multiple content types with the following syntax:
"SELECT Title, URL FROM Scope() WHERE ContentType = 'Article Page' OR ContentType = 'Page' OR ContentType = 'Welcome Page' ORDER BY RANK"
As you can see with a little playing around you can get any of the fields to show up and then use them in the search. In the next few posts I will expand on how we can use the Search API to produce some powerful results.
One of the only issues that I have found is the issue of certain fields not showing up in the search results. This is a pain and can stop you deciding to use it. Even though the field is indexed and is present in the Shared Service Provider it does not show up in the search results. To show you how you can expand the code slightly I have changed my initial form to include the following:
This check runs some kind during the search process and grabs the relevant "PublishingRollupImage" details. This is basically using a CAML query based on the URL of the item found in the search.
The result is the following:
In the next part we will look at moving this into the SharePoint and changing the output to XML and using XSLT to style it. J