Полнотекстовый поиск SQL Server - отношение многие ко многим - PullRequest
4 голосов
/ 04 марта 2012

Я работаю над проектом с SQL Server 2008, где я считаю, что полнотекстовый поиск - лучший путь.Я читал об этом столько, сколько я могу, и в значительной степени понимаю, как настроить его для одной таблицы.Однако я не совсем уверен, как настроить это в моем сценарии - представьте следующую структуру таблицы:

Книга

- Id
- Title
- Description

BookAuthor

- BookId
- AuthorId

Автор

- Id
- Name

Как видите, в базе данных содержится таблица с книгами, и у каждой книги может не быть ни одного, ни одного, ни нескольких авторов.,Каждый автор также может быть частью ни одной, одной или нескольких книг - то есть таблицы Book и Author имеют отношение многие ко многим и обрабатываются таблицей ссылок BookAuthor.

Что яна этом этапе хотите выполнить поиск - это инструмент для поиска подходящих книг на основе строки поиска, которую предоставляет пользователь.Поэтому, если пользователь вводит Brown, я бы хотел найти все книги, в которых любой из следующих столбцов содержит слово Brown:

Book.Title
Book.Description
Author.Name

По сути, мне нужен набор результатов, включаяи книга с названием Brown Bear и книги, написанные автором Dan Brown.Если есть какие-либо предложения относительно того, как мне это настроить, я буду очень признателен за ваш ввод!

(в качестве примечания, как только у меня будет работать эта фильтрация, результат запроса будеттакже должны быть сортируемыми и доступными для страниц, обрабатываться с помощью @SortOrder, @PageIndex и @PageSize, передаваемых в хранимую процедуру - но я думаю, что это может быть отдельный вопрос впоследствии!)

1 Ответ

2 голосов
/ 04 марта 2012

Предикат CONTAINS может принимать список столбцов для поиска в качестве первого аргумента;однако эти столбцы должны быть из одной таблицы.У вас есть несколько вариантов, чтобы обойти это ограничение.Один из вариантов заключается в том, что вы можете выполнить два отдельных поиска, по одному в каждой таблице, а затем объединить результаты вместе.

select Id, Title from Book where contains([Description], 'brown')
union
select b.Id, b.Title
    from Book b inner join BookAuthor ba on b.Id = ba.BookId
        inner join Author a on a.Id=ba.AuthorId
    where contains([Name], 'brown')

Другой вариант - воспользоваться тем, что можно создавать индексы FTS.в индексированных представлениях .Для этого создайте индексированное представление, которое содержит как поле «Заголовок» из таблицы «Книга», так и поле «Имя» из таблицы «Автор», а затем создайте индекс FTS для обоих столбцов в представлении.Затем вы можете написать запросы для этого представления следующим образом:

select BookId, Title from vw_BooksAndAuthors 
where contains(([Description], [Name]), 'brown')
...