Как назначить веса различным столбцам в полнотекстовом поиске? - PullRequest
9 голосов
/ 13 октября 2008

В моем полнотекстовом поисковом запросе я хочу присвоить определенным столбцам более высокий вес. Рассмотрим этот запрос:

SELECT Key_Table.RANK, FT_Table.* FROM Restaurants AS FT_Table
INNER JOIN FREETEXTTABLE(Restaurants, *, 'chilly chicken') AS Key_Table
ON FT_Table.RestaurantID = Key_Table.[KEY]
ORDER BY Key_Table.RANK DESC

Теперь я хочу, чтобы столбец «Имя» имел больший вес в результатах («Имя», «Ключевые слова» и «Местоположение» имеют полнотекстовую индексацию). В настоящее время, если результат найден в любом из трех столбцов, ранги не затрагиваются.

Например, я бы хотел, чтобы строка с именем "Chilly Chicken" имела более высокий ранг, чем строка с ключевыми словами "Chilly Chicken", но с другим именем.

Edit:

Я не хочу использовать ContainsTable, потому что это будет означать разделение фраз (Chilly AND Chicken и т. Д.), Что потребует от меня поиска всех возможных комбинаций - Chilly AND Chicken, Chilly OR Chicken и т. Д. I хотел бы, чтобы механизм FTS автоматически определял, какие результаты соответствуют лучше всего, и я думаю, что FREETEXT отлично справляется с этой задачей.

Извините, если я неправильно понял, как работает CONTAINS / CONTAINSTABLE.

1 Ответ

7 голосов
/ 14 октября 2008

Лучшее решение - использовать ContainsTable. Используйте объединение, чтобы создать запрос, который ищет все 3 столбца и добавляет целое число, используемое для указания того, какой столбец был найден. Сортируйте результаты по этому целому числу и затем ранжируйте desc.

Ранг является внутренним для сервера sql и не может быть изменен.

Вы также можете манипулировать рангом , возвращенным , поделив ранг на целое число (имя будет разделено на 1, ключевое слово и местоположение на 2 или выше). Это вызвало бы появление разных рейтингов.

Вот несколько примеров sql
: - Рекомендовать использовать отслеживание изменений начала и запускать фоновое обновление индекса (см. Книги в Интернете)

    SELECT 1 AS ColumnLocation, Key_Table.Rank, FT_Table.* FROM Restaurants AS FT_Table
 INNER JOIN ContainsTable(Restaurant, Name, 'chilly chicken') AS Key_Table ON 
FT_Table.RestaurantId = Key_Table.[Key]

UNION SELECT 2 AS ColumnLocation, Key_Table.Rank, FT_Table.* FROM Restaurants AS FT_Table
 INNER JOIN ContainsTable(Restaurant, Keywords, 'chilly chicken') AS Key_Table ON 
FT_Table.RestaurantId = Key_Table.[Key]

UNION SELECT 3 AS ColumnLocation, Key_Table.Rank, FT_Table.* FROM Restaurants AS FT_Table
 INNER JOIN ContainsTable(Restaurant, Location, 'chilly chicken') AS Key_Table ON 
FT_Table.RestaurantId = Key_Table.[Key]

ORDER BY ColumnLocation, Rank DESC

В производственной среде я бы вставил выходные данные запроса в табличную переменную для выполнения каких-либо дополнительных манипуляций перед возвратом результатов (в этом случае может не потребоваться). Кроме того, избегайте использования *, просто перечислите столбцы, которые вам действительно нужны.

Редактировать: Вы правы в использовании ContainsTable, вам нужно изменить ключевые слова на «chilly *» И «курица *», я делаю это с помощью процесса, который токенизирует входную фразу. Если вы не хотите этого делать, просто замените каждый вышеупомянутый экземпляр ContainsTable на FreeTextTable, запрос все равно будет работать так же.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...