Searching on SQLTeam.comBy Bill Graziano on 2 January 2001 | Tags: Application Design Many web sites like this one give each article their own web page. My site stores each article as a field in the database. This article shows you how I wrote a search function that ranks the results.
If you take a quick look at my search page, you'll see that you can enter keywords and it will search the database for those words and rank the results based on where and how it finds those words. (Update: My first choice for searching was full-text indexing. Unfortunately my host doesn't offer that on shared servers. Can't say as I blame them either.)
My first step was to pass the list of words to search to a stored procedure. My ASP code looks like this:
All the searching is done in the stored procedure My articles are stored in a table called The first part of the stored procedure creates a temporary table. I'll use this table to hold the ItemID's of the records that the search finds.
Next I'm going to loop through each word passed in to the procedure: -- For my loop to work I need an extra separator at the end. I always look to the -- left of the separator character for each array value set @array = @array + @separator -- Loop through the string searching for separtor characters while patindex('%' + @separator + '%' , @array) <> 0 begin -- patindex matches the a pattern against a string select @separator_position = patindex('%' + @separator + '%' , @array) select @array_value = left(@array, @separator_position - 1) select @like_text = '%' + @array_value + '%' The variable INSERT #SearchResults SELECT ItemID FROM vActiveItems WHERE Title like @like_text INSERT #SearchResults SELECT ItemID FROM vActiveItems WHERE Abstract like @like_text INSERT #SearchResults SELECT ItemID FROM vActiveItems WHERE Story like @like_text -- This replaces what we just processed with an empty string select @array = stuff(@array, 1, @separator_position, '') end That snippet shows my three INSERT/SELECT statements and the code to finish the loop. If a given word appears only in the Title, it's ItemID will only be in the #SearchResults table once. If it appears in two of the searches, the ItemID will be in the table twice. If I'm searching on two words and they both appear in the title, the ItemID will be placed in the #SearchResults table twice. This is how I do the rankings of the search results. Last is my statement to return the results to the calling ASP page: SELECT TOP 50 S.ItemID, I.Title, DatePosted=Convert(varchar, I.DatePosted, 101), I.URL, Rating=Count(*) FROM #SearchResults S, vActiveItems I WHERE S.ItemID = I.ItemID Group by S.ItemID, I.Title, I.DatePosted, I.URL Order by 5 DESC, 3 DESC set nocount off GO I use a GROUP BY clause and order the results by the count of times each item appears in the result set. I use the ordinal position of the fields to ORDER BY rather than the field names. This makes it easier to sort when you are using a GROUP BY clause. I also limit my search to 50 items. I'd like to enhance this code to weight the different searches. For example, finding a word in the Title should be worth more than finding it in the article body. You could also enhance this to make the number of stories dynamic or to page the result sets. But that's a project for another day. You can see the complete text of the stored procedure here. |
- Advertisement - |