views:

54

answers:

2

Hello, I have added Full Text Search to my sql server 2008 express database and created an index catalog for two columns in a single table. So now, I have to rewrite one of my stored procedures but I have no idea where to begin. The following is my current SP that I need to convert to take advantage of the full text search capability:

ALTER PROCEDURE [dbo].[sp_page_GetPostsBySearchFront]
(
 @Title nvarchar(256), 
 @Content nvarchar(MAX), 
 @startRowIndex INT,
 @maximumRows INT
) 
AS 
BEGIN
SELECT 
  RowNumber, 
  postId, 
  Title, 
  Content, 
  DateCreated, 
  IsPublished, 
  PublishOnDate, 
  Type, 
  MenuName 
FROM 
(
SELECT ROW_NUMBER() OVER (ORDER BY posts.postId DESC) AS RowNumber, 
  posts.postId, 
  posts.Title, 
  posts.Content, 
  posts.DateCreated, 
  posts.IsPublished, 
  posts.PublishOnDate, 
  posts.Type, 
  posts.MenuName 
FROM posts 
GROUP BY 
  posts.postId, 
  posts.Title, 
  posts.Content, 
  posts.DateCreated, 
  posts.IsPublished, 
  posts.PublishOnDate, 
  posts.Type, 
  posts.MenuName 
HAVING (posts.Title LIKE N'%' + @Title + N'%') 
OR (posts.Content LIKE N'%' + @Content + N'%') 
AND (posts.IsPublished = 1) 
AND (posts.PublishOnDate <= GETDATE()) 
) as u
WHERE u.RowNumber > @startRowIndex 
AND u.RowNumber <= (@startRowIndex + @maximumRows) 

END

Could some one explain how I go about accomplishing this task? Do I use CONTAINS or FREETEXT and where do I add it. I'm just lost on this? Thank you!

+1  A: 

Use:

WITH cte AS (
    SELECT ROW_NUMBER() OVER (ORDER BY p.postId DESC) AS RowNumber, 
           p.postId, 
           p.Title, 
           p.Content, 
           p.DateCreated, 
           p.IsPublished, 
           p.PublishOnDate, 
           p.Type, 
           p.MenuName 
      FROM POSTS p
     WHERE (   CONTAINS(p.title, @Title)
            OR CONTAINS(p.content, @Content))
       AND p.IsPublished = 1
       AND p.PublishOnDate <= GETDATE() )
 SELECT u.RowNumber, 
        u.postId, 
        u.Title, 
        u.Content, 
        u.DateCreated, 
        u.IsPublished, 
        u.PublishOnDate, 
        u.Type, 
        u.MenuName 
   FROM cte as u
  WHERE u.RowNumber > @startRowIndex 
    AND u.RowNumber <= (@startRowIndex + @maximumRows)

Too bad you have different parameters for searching the title and content fields - could've been consolidated into a single CONTAINS if the parameters are the same value.

The documentation provides a nice breakdown of when they suggest Full Text Search (FTS) functionality. The majority of examples suggest CONTAINS/CONTAINSTABLE, and use FREETEXT/FREETEXTTABLE for:

  • The inflectional forms are the different tenses of a verb or the singular and plural forms of a noun.
  • A thesaurus defines user-specified synonyms for terms.
OMG Ponies
OK, I modified the query using a single parameter as follows but its not working. I get a message that there are noise words.
Scott W.
ALTER PROCEDURE [dbo].[sp_page_GetPostsByFTS]( @search nvarchar, @startRowIndex INT, @maximumRows INT) AS BEGINSELECT RowNumber, postId, Title, Content, DateCreated, IsPublished, PublishOnDate, Type, MenuName FROM (SELECT ROW_NUMBER() OVER (ORDER BY posts.postId DESC) AS RowNumber, posts.postId, posts.Title, posts.Content, posts.DateCreated, posts.IsPublished, posts.PublishOnDate, posts.Type, posts.MenuName FROM posts WHERE CONTAINS((Title, Content), @search) ) as uWHERE u.RowNumber > @startRowIndex AND u.RowNumber <= (@startRowIndex + @maximumRows) END
Scott W.
@Scott W.: That's an issue you have with your FTS, requiring that you either [tune the noise words](http://www.sqlnewsgroups.net/group/microsoft.public.sqlserver.server/topic24791.aspx), or [encapsulate the results of the parameters (@Tile, @Content) inside of double quotes](http://social.msdn.microsoft.com/Forums/en-US/transactsql/thread/34a3b6fb-275c-4ff7-a547-d9de43aee943).
OMG Ponies
A: 

OK, Here is what I did to make it work. The reason why I was receiving the noise word message is because I did not set the parameter value length @search correctly. Once I realized that and changed it, it works fine.

ALTER PROCEDURE [dbo].[sp_page_GetPostsByFTS] ( @search nvarchar(255), @startRowIndex INT, @maximumRows INT ) AS BEGIN SELECT RowNumber, postId, Title, Content, DateCreated, IsPublished, PublishOnDate, Type, MenuName FROM ( SELECT ROW_NUMBER() OVER (ORDER BY posts.postId DESC) AS RowNumber, posts.postId, posts.Title, posts.Content, posts.DateCreated, posts.IsPublished, posts.PublishOnDate, posts.Type, posts.MenuName FROM posts WHERE FREETEXT((Title,Content),@search) AND (posts.IsPublished = 1) AND (posts.PublishOnDate <= GETDATE()) ) as u WHERE u.RowNumber > @startRowIndex AND u.RowNumber <= (@startRowIndex + @maximumRows) END

Scott W.