I’m working on a project with SQL Server 2008 where I believe full-text search is the best way to go. I’ve been reading up on it as much as I can, and pretty much understand hos to set it up for a single table. However I’m not entirely sure how to set it up with my scenario – imagine the following table structure:
Book
- Id
- Title
- Description
BookAuthor
- BookId
- AuthorId
Author
- Id
- Name
As you can see, the database holds a table with books, and each book can have none, one or many authors. Each author can also be part of none, one or many books – i.e. the Book and Author tables have a many-to-many relationship, handled with the linking table BookAuthor.
What I want to accomplish at this point is a search tool to find matching books based on a search string the user provides. So if the user types in Brown I would want to find all books where either of the following columns contains the word Brown:
Book.Title
Book.Description
Author.Name
In essence, I want a result set of books, including both the book with the title Brown Bear and the books written by author Dan Brown. If there are any suggestions out there as to how I should set this up, I’d really appreciate your input!
(as a side note, once I have this filtering working, the query result would also need to be sortable and pageable, handled via @SortOrder, @PageIndex and @PageSize passed into a Stored Procedure – but I guess that could be a separate question afterwards!)
A CONTAINS predicate can take a list of columns to search as its first argument; however, these columns must be from a single table. You have a couple of options for getting around this limitation. One option is that you can perform two separate searches, one on each table, and then UNION the results together.
Another option is to take advantage of the fact that FTS indexes can be created on indexed views. To do this, create an indexed view that contains both the Title field from the Book table and the Name field from the Author table, and then create a FTS index on both of these columns in the view. Then you can write queries against this view as follows: